diff options
author | Galen Guyer <galen@galenguyer.com> | 2023-01-13 23:24:11 -0500 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2023-01-13 23:24:11 -0500 |
commit | 498df4745e36e5c679221f03845207a2cb1b40db (patch) | |
tree | fb826af23269e3bc3b9a60e48cde5bd644e191a8 | |
parent | 9838daa8187e138da3eeb0c317edb010c7eda67a (diff) |
add create-repo and create-chroot commands
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | README.md | 19 | ||||
-rw-r--r-- | makepkg.conf | 162 | ||||
-rw-r--r-- | pacman.conf | 92 | ||||
-rw-r--r-- | src/bin/build-pkg.rs | 22 | ||||
-rw-r--r-- | src/bin/create-chroot.rs | 63 | ||||
-rw-r--r-- | src/bin/create-repo.rs | 31 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 4 |
10 files changed, 398 insertions, 4 deletions
@@ -28,6 +28,12 @@ dependencies = [ ] [[package]] +name = "anyhow" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" + +[[package]] name = "async-compression" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -521,6 +527,7 @@ name = "pkgbuild" version = "0.1.0" dependencies = [ "alpm", + "anyhow", "reqwest", "serde", "serde_json", @@ -9,6 +9,7 @@ edition = "2021" [dependencies] alpm = "2.2.1" +anyhow = "1.0.68" reqwest = { version = "0.11.13", features = ["json", "gzip"] } serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" @@ -5,3 +5,22 @@ Steps: 1. Sort packages by popularity Depends on aurutils + +## building +https://wiki.archlinux.org/title/DeveloperWiki:Building_in_a_clean_chroot +```bash +sudo mkdir /var/lib/pkgbuild +mkdir -p $HOME/.cache/pkgbuild +sudo chown "$(id -un)":"$(id -gn)" /var/lib/pkgbuild +mkarchroot -C pacman.conf -M makepkg.conf /var/lib/pkgbuild/root base-devel +export NAME= +git clone --single-branch --branch=$NAME $HOME/aur.git $HOME/.cache/pkgbuild/$NAME +cd $HOME/.cache/pkgbuild/$NAME +makechrootpkg -l "$(git branch --show-current)" -r /var/lib/pkgbuild -- --skippgpcheck -s +gpg --detach-sign --output "$(makepkg --packagelist).sig" "$(makepkg --packagelist)" +``` + +## new repo +``` +repo-add -s "$REPO_ROOT/$REPO_NAME.db.tar.zst" +```
\ No newline at end of file diff --git a/makepkg.conf b/makepkg.conf new file mode 100644 index 0000000..5cf72d4 --- /dev/null +++ b/makepkg.conf @@ -0,0 +1,162 @@ +#!/hint/bash +# shellcheck disable=2034 + +# +# /etc/makepkg.conf +# + +######################################################################### +# SOURCE ACQUISITION +######################################################################### +# +#-- The download utilities that makepkg should use to acquire sources +# Format: 'protocol::agent' +DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u' + 'ftp::/usr/bin/curl -qgfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u' + 'http::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'https::/usr/bin/curl -qgb "" -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'rsync::/usr/bin/rsync --no-motd -z %u %o' + 'scp::/usr/bin/scp -C %u %o') + +# Other common tools: +# /usr/bin/snarf +# /usr/bin/lftpget -c +# /usr/bin/wget + +#-- The package required by makepkg to download VCS sources +# Format: 'protocol::package' +VCSCLIENTS=('bzr::bzr' + 'fossil::fossil' + 'git::git' + 'hg::mercurial' + 'svn::subversion') + +######################################################################### +# ARCHITECTURE, COMPILE FLAGS +######################################################################### +# +CARCH="x86_64" +CHOST="x86_64-pc-linux-gnu" + +#-- Compiler and Linker Flags +#CPPFLAGS="" +CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions \ + -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \ + -fstack-clash-protection -fcf-protection" +CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" +LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" +LTOFLAGS="-flto=auto" +#RUSTFLAGS="-C opt-level=2" +#-- Make Flags: change this for DistCC/SMP systems +MAKEFLAGS="-j$(nproc)" +#-- Debugging flags +DEBUG_CFLAGS="-g" +DEBUG_CXXFLAGS="$DEBUG_CFLAGS" +#DEBUG_RUSTFLAGS="-C debuginfo=2" + +######################################################################### +# BUILD ENVIRONMENT +######################################################################### +# +# Makepkg defaults: BUILDENV=(!distcc !color !ccache check !sign) +# A negated environment option will do the opposite of the comments below. +# +#-- distcc: Use the Distributed C/C++/ObjC compiler +#-- color: Colorize output messages +#-- ccache: Use ccache to cache compilation +#-- check: Run the check() function if present in the PKGBUILD +#-- sign: Generate PGP signature file +# +BUILDENV=(!distcc color !ccache check !sign) +# +#-- If using DistCC, your MAKEFLAGS will also need modification. In addition, +#-- specify a space-delimited list of hosts running in the DistCC cluster. +#DISTCC_HOSTS="" +# +#-- Specify a directory for package building. +#BUILDDIR=/tmp/makepkg + +######################################################################### +# GLOBAL PACKAGE OPTIONS +# These are default values for the options=() settings +######################################################################### +# +# Makepkg defaults: OPTIONS=(!strip docs libtool staticlibs emptydirs !zipman !purge !debug !lto) +# A negated option will do the opposite of the comments below. +# +#-- strip: Strip symbols from binaries/libraries +#-- docs: Save doc directories specified by DOC_DIRS +#-- libtool: Leave libtool (.la) files in packages +#-- staticlibs: Leave static library (.a) files in packages +#-- emptydirs: Leave empty directories in packages +#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip +#-- purge: Remove files specified by PURGE_TARGETS +#-- debug: Add debugging flags as specified in DEBUG_* variables +#-- lto: Add compile flags for building with link time optimization +# +OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !debug lto) + +#-- File integrity checks to use. Valid: md5, sha1, sha224, sha256, sha384, sha512, b2 +INTEGRITY_CHECK=(sha256) +#-- Options to be used when stripping binaries. See `man strip' for details. +STRIP_BINARIES="--strip-all" +#-- Options to be used when stripping shared libraries. See `man strip' for details. +STRIP_SHARED="--strip-unneeded" +#-- Options to be used when stripping static libraries. See `man strip' for details. +STRIP_STATIC="--strip-debug" +#-- Manual (man and info) directories to compress (if zipman is specified) +MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info}) +#-- Doc directories to remove (if !docs is specified) +DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc}) +#-- Files to be removed from all packages (if purge is specified) +PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) +#-- Directory to store source code in for debug packages +DBGSRCDIR="/usr/src/debug" + +######################################################################### +# PACKAGE OUTPUT +######################################################################### +# +# Default: put built package and cached source in build directory +# +#-- Destination: specify a fixed directory where all packages will be placed +#PKGDEST=/home/packages +#-- Source cache: specify a fixed directory where source files will be cached +#SRCDEST=/home/sources +#-- Source packages: specify a fixed directory where all src packages will be placed +#SRCPKGDEST=/home/srcpackages +#-- Log files: specify a fixed directory where all log files will be placed +#LOGDEST=/home/makepkglogs +#-- Packager: name/email of the person or organization building packages +#PACKAGER="John Doe <john@doe.com>" +#-- Specify a key to use for package signing +#GPGKEY="" + +######################################################################### +# COMPRESSION DEFAULTS +######################################################################### +# +COMPRESSGZ=(gzip -c -f -n) +COMPRESSBZ2=(bzip2 -c -f) +COMPRESSXZ=(xz -c -z -) +COMPRESSZST=(zstd -c -T0 --ultra -20 -) +COMPRESSLRZ=(lrzip -q) +COMPRESSLZO=(lzop -q) +COMPRESSZ=(compress -c -f) +COMPRESSLZ4=(lz4 -q) +COMPRESSLZ=(lzip -c -f) + +######################################################################### +# EXTENSION DEFAULTS +######################################################################### +# +PKGEXT='.pkg.tar.zst' +SRCEXT='.src.tar.gz' + +######################################################################### +# OTHER +######################################################################### +# +#-- Command used to run pacman as root, instead of trying sudo and su +#PACMAN_AUTH=() +# vim: set ft=sh ts=2 sw=2 et: diff --git a/pacman.conf b/pacman.conf new file mode 100644 index 0000000..768c96d --- /dev/null +++ b/pacman.conf @@ -0,0 +1,92 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +#[testing] +#Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +#[community-testing] +#Include = /etc/pacman.d/mirrorlist + +[community] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/src/bin/build-pkg.rs b/src/bin/build-pkg.rs new file mode 100644 index 0000000..1ec422f --- /dev/null +++ b/src/bin/build-pkg.rs @@ -0,0 +1,22 @@ +#[tokio::main] +async fn main() { + let package_name = std::env::args().nth(1).expect("No package name given"); + let package_list = pkgbuild::latest_package_list().await; + + let handle = pkgbuild::setup_alpm(); + + let package = package_list.iter().find(|p| p.name == package_name); + if package.is_none() { + println!("Package {} not found", package_name); + return; + } + + let package = package.expect("package is None"); + let dependencies = package.resolve_dependencies(&handle, &package_list); + for dependency in dependencies.iter().filter(|d| match d { + pkgbuild::Dependency::AUR(_) => true, + _ => false, + }) { + dbg!(dependency); + } +} diff --git a/src/bin/create-chroot.rs b/src/bin/create-chroot.rs new file mode 100644 index 0000000..185a629 --- /dev/null +++ b/src/bin/create-chroot.rs @@ -0,0 +1,63 @@ +use std::process::{Child, Command, Output}; + +fn main() { + let chroot_dir = std::env::var("PKGBUILD_CHROOT_DIR") + .unwrap_or_else(|_| String::from("/var/lib/pkgbuild")) + .trim_end_matches('/') + .to_string(); + + let mut command = Command::new("mkdir"); + command.arg("-p").arg(&chroot_dir); + dbg!(&command); + print_status(command.spawn()); + + + let mut command = Command::new("chown"); + command + .arg(format!( + "{}:{}", + get_username().unwrap(), + get_groupname().unwrap() + )) + .arg(&chroot_dir); + dbg!(&command); + print_status(command.spawn()); + + + let mut command = Command::new("mkarchroot"); + command + .arg("-C") + .arg("pacman.conf") + .arg("-M") + .arg("makepkg.conf") + .arg(format!("{chroot_dir}/root")) + .args(["base-devel"]); + dbg!(&command); + print_status(command.spawn()); +} + +fn print_status(output: Result<Child, std::io::Error>) { + match output { + Ok(mut child) => match child.wait() { + Ok(status) => { + println!("STATUS: {}", status.code().unwrap_or(-1)); + } + Err(e) => { + println!("ERROR: {e}"); + } + }, + Err(e) => { + println!("ERROR: {e}"); + } + } +} + +fn get_username() -> anyhow::Result<String> { + let output = Command::new("id").arg("-un").output()?; + Ok(String::from_utf8(output.stdout)?.trim().to_string()) +} + +fn get_groupname() -> anyhow::Result<String> { + let output = Command::new("id").arg("-gn").output()?; + Ok(String::from_utf8(output.stdout)?.trim().to_string()) +} diff --git a/src/bin/create-repo.rs b/src/bin/create-repo.rs new file mode 100644 index 0000000..4aef40c --- /dev/null +++ b/src/bin/create-repo.rs @@ -0,0 +1,31 @@ +use std::process::Command; + +fn main() { + let mut command = Command::new("repo-add"); + if let Ok(gpg_sign) = std::env::var("PKGBUILD_GPG_SIGN") { + if gpg_sign == "true" || gpg_sign == "1" { + command.arg("--sign"); + } + } + if let Ok(gpg_key) = std::env::var("PKGBUILD_GPG_KEY") { + command.arg("--key").arg(gpg_key); + } + command.arg(format!( + "{}/{}.db.tar.zst", + std::env::var("PKGBUILD_REPO_ROOT").expect("PKGBUILD_REPO_ROOT not set").trim_end_matches('/'), + std::env::var("PKGBUILD_REPO_NAME").expect("PKGBUILD_REPO_NAME not set"), + )); + + let output = command.output(); + + match output { + Ok(output) => { + println!("STATUS: {}", output.status); + println!("===== STDOUT =====\n{}", String::from_utf8_lossy(&output.stdout)); + println!("===== STDERR =====\n{}", String::from_utf8_lossy(&output.stderr)); + } + Err(e) => { + println!("ERROR: {}", e); + } + } +} @@ -22,6 +22,7 @@ pub struct PackageMeta { pub check_depends: Option<Vec<String>>, } +#[derive(Debug)] pub enum Dependency { Official(String), AUR(PackageMeta), diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index d3027c6..0000000 --- a/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[tokio::main] -async fn main() { - println!("{:#?}", pkgbuild::latest_package_list().await) -}
\ No newline at end of file |