new: mtsc-common, mp-build and mp-pool

This commit is contained in:
ngn 2024-08-11 17:45:54 +03:00
parent e9db1d41a5
commit aa5fbb82d6
26 changed files with 1619 additions and 478 deletions

View File

@ -1,15 +1,14 @@
SUBDIRS := $(wildcard */.)
prefix = /usr prefix = /usr
install: install:
install -v -m755 matter-mirror/main.py $(DESTDIR)$(prefix)/bin/matter-mirror @for dir in $(SUBDIRS) ; do \
install -v -m755 matter-chroot/main.sh $(DESTDIR)$(prefix)/bin/matter-chroot $(MAKE) -C "$$dir" install ; \
install -v -m755 matter-base/main.sh $(DESTDIR)$(prefix)/bin/matter-base done
install -v -m755 matter-iso/main.sh $(DESTDIR)$(prefix)/bin/matter-iso
uninstall: uninstall:
rm -v $(DESTDIR)$(prefix)/bin/matter-mirror @for dir in $(SUBDIRS) ; do \
rm -v $(DESTDIR)$(prefix)/bin/matter-chroot $(MAKE) -C "$$dir" uninstall ; \
rm -v $(DESTDIR)$(prefix)/bin/matter-base done
rm -v $(DESTDIR)$(prefix)/bin/matter-iso
.PHONY: install uninstall .PHONY: install uninstall

View File

@ -1,6 +1,7 @@
# tools | Matterlinux Tools and Scripts Collection # mtsc | MatterLinux tools and scripts collection
This repository contains different tools and scripts This repository contains different tools and scripts
for general matterlinux installation and configuration. for general MatterLinux installation, configuration and
build process.
### Installation ### Installation
All the tools and scripts can be copied to PATH with All the tools and scripts can be copied to PATH with
@ -8,10 +9,14 @@ the make script:
``` ```
make install make install
``` ```
You can also install the mtsc package from the base package
pool.
### Usage ### Usage
All tools/scripts contains usage information in README files: All tools/scripts contains usage information in README files:
- [mtsc-common](mtsc-common/README.md)
- [matter-chroot](matter-chroot/README.md) - [matter-chroot](matter-chroot/README.md)
- [matter-mirror](matter-mirror/README.md)
- [matter-base](matter-base/README.md) - [matter-base](matter-base/README.md)
- [matter-iso](matter-iso/README.md) - [matter-iso](matter-iso/README.md)
- [mp-build](mp-build/README.md)
- [mp-pool](mp-pool/README.md)

9
matter-base/Makefile Normal file
View File

@ -0,0 +1,9 @@
PREFIX = /usr
install:
install -m755 "main.sh" $(DESTDIR)/$(PREFIX)/bin/matter-base
uninstall:
rm $(DESTDIR)/$(PREFIX)/lib/matter-base
.PHONY: install uninstall

View File

@ -3,7 +3,7 @@ This script is used for building release archives.
### Usage ### Usage
Note that you will need to install and configure Note that you will need to install and configure
[`mp`](https://git.matterlinux.xyz/matterlinux/mp) before using [`matt`](https://git.matterlinux.xyz/matterlinux/matt) before using
`matter-base`. `matter-base`.
To use the `matter-base` script, specify a temporary target To use the `matter-base` script, specify a temporary target

115
matter-base/main.sh Normal file → Executable file
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# matter-base | Matterlinux Release Archive Build Script # matter-base | MatterLinux release archive build script
# MatterLinux 2023-2024 (https://matterlinux.xyz) # MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -16,66 +16,54 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
############################ #############################
## logging functions/vars ## ## import common functions ##
############################ #############################
BOLD="\e[1m" location="$(dirname "${0}")"
RESET="\e[0m" location="$(realpath "${location}")"
GREEN="\e[32m" commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
BLUE="\e[34m"
GRAY="\e[37m"
RED="\e[31m"
success() { source "${commonsh}"
echo -e "$BOLD$GREEN>>>$RESET$BOLD $1$RESET"
}
info() { if [ "${?}" != "0" ]; then
echo -e "$BOLD$BLUE>>>$RESET$BOLD $1$RESET" echo "Failed to import mtsc-common"
}
error() {
echo -e "$BOLD$RED>>>$RESET$BOLD $1$RESET"
exit 1 exit 1
} fi
####################
## util functions ##
####################
check_ret() {
if [ $? -ne 0 ]; then
error "$1"
fi
}
################# #################
## main script ## ## main script ##
################# #################
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
error "You should run this script as root" error "You should run this script as root"
exit 1
fi fi
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
error "Please specify a name for the archive" error "Please specify a name for the archive"
exit 1
fi fi
NAME="$1" name="${1}"
TARGET="$(realpath $1)" target="$(realpath "${1}")"
if [ -d $TARGET ]; then
if [ -d "${target}" ]; then
error "A directory with the specified archive name exists" error "A directory with the specified archive name exists"
exit 1
fi fi
mkdir $TARGET mkdir "${target}"
if ! type mp > /dev/null; then if ! type matt > /dev/null; then
error "mp is not installed, please install and configure mp" error "matt is not installed, please install and configure matt"
exit 1
fi fi
info "Creating directory structure" info "Creating directory structure"
pushd $TARGET > /dev/null pushd "${target}" > /dev/null
mkdir -p {dev,proc,sys,run,tmp,root,home,boot,mnt} install -Ddm755 {dev,proc,sys,run,tmp,root,home,boot,mnt}
mkdir -p var/{log,mail,lib} install -Ddm755 var/{log,mail,lib}
mkdir -p usr/{bin,lib,sbin} install -Ddm755 usr/{bin,lib,sbin}
mkdir -p etc/mp install -Ddm755 var/lib/matt
install -Ddm755 etc/matt
ln -sf usr/lib lib ln -sf usr/lib lib
ln -sf usr/lib lib64 ln -sf usr/lib lib64
@ -126,25 +114,24 @@ EOF
EOF EOF
popd > /dev/null popd > /dev/null
export MP_ROOT="$TARGET" MP_YES=1 info "Syncing repositories"
info "Syncing repositories" matt sync --root "${target}" --yes
mp-sync check_ret "matt command failed"
check_ret "mp-sync command failed"
info "Installing base system packages" info "Installing base system packages"
mp-install acl attr coreutils binutils \ matt install --root "${target}" --yes \
bash e2fsprogs udev file release \ acl attr coreutils binutils \
findutils gawk grep gzip iana-etc \ bash e2fsprogs udev file release \
inetutils intltool iproute kmod less \ findutils gawk grep gzip iana-etc \
openssl sed shadow tar tcl mandb \ inetutils intltool iproute kmod less \
man-pages tzdata util-linux which \ openssl sed shadow tar tcl mandb \
mp gettext iproute procps psmisc \ man-pages tzdata util-linux which \
mandb kbd dbus vim nano libxml2 matt gettext iproute procps psmisc \
check_ret "mp-install command failed" mandb kbd dbus vim nano libxml2
unset MP_ROOT MP_YES check_ret "matt command failed"
success "Installed the base system" success "Installed the base system"
cat > $TARGET/etc/inputrc << "EOF" cat > "${target}/etc/inputrc" << "EOF"
# do not bell on tab-completion # do not bell on tab-completion
#set bell-style none #set bell-style none
@ -183,24 +170,24 @@ $if mode=emacs
$endif $endif
EOF EOF
cat > $TARGET/etc/shells << "EOF" cat > "${target}/etc/shells" << "EOF"
/bin/sh /bin/sh
/bin/bash /bin/bash
EOF EOF
cp "$TARGET/etc/skel/."* "$TARGET/root" cp "${target}/etc/skel/."* "${target}/root"
info "Installing certs" info "Installing certs"
wget -q https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt -O "$TARGET/certdata.txt" wget --show-progress -q https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt -O "${target}/certdata.txt"
matter-chroot $TARGET make-ca > /dev/null matter-chroot "${target}" make-ca > /dev/null
check_ret "Failed to run make-ca, install certs manually" check_ret "Failed to run make-ca, install certs manually"
rm -f "$TARGET/certdata.txt" rm -f "${target}/certdata.txt"
info "Setup complete, now creating the archive..." info "Setup complete, now creating the archive..."
pushd $TARGET > /dev/null pushd "${target}" > /dev/null
tar czf ../${NAME}.tar.gz * tar czf ../${name}.tar.gz *
check_ret "Failed to create the archive" check_ret "Failed to create the archive"
popd > /dev/null popd > /dev/null
success "Archive created, now cleaning up" success "Archive created, now cleaning up"
rm -rf $TARGET && success "Build completed" rm -rf "${target}" && success "Build completed"

9
matter-chroot/Makefile Normal file
View File

@ -0,0 +1,9 @@
PREFIX = /usr
install:
install -m755 "main.sh" $(DESTDIR)/$(PREFIX)/bin/matter-chroot
uninstall:
rm $(DESTDIR)/$(PREFIX)/lib/matter-chroot
.PHONY: install uninstall

91
matter-chroot/main.sh Normal file → Executable file
View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# matter-chroot | Matterlinux Chroot Script # matter-chroot | MatterLinux chroot script
# MatterLinux 2023-2024 (https://matterlinux.xyz) # MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -16,67 +16,71 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
############################ #############################
## logging functions/vars ## ## import common functions ##
############################ #############################
RED="\e[31m" location="$(dirname "${0}")"
BOLD="\e[1m" location="$(realpath "${location}")"
RESET="\e[0m" commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
error() { source "${commonsh}"
echo -e "$BOLD$RED>>>$RESET$BOLD $1$RESET"
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1 exit 1
} fi
#################### ####################
## util functions ## ## util functions ##
#################### ####################
linkresolv(){ linkresolv(){
if [ ! -f "$TARGET/etc/resolv.conf" ]; then if [ ! -f "${target}/etc/resolv.conf" ]; then
ln -sf /run/systemd/resolve/resolv.conf "$TARGET/etc/resolv.conf" ln -sf /run/systemd/resolve/resolv.conf "${target}/etc/resolv.conf"
fi fi
} }
chrt() { chrt() {
mount -t proc proc "$TARGET/proc" mount -t proc proc "${target}/proc"
mount -t sysfs sysfs "$TARGET/sys" mount -t sysfs sysfs "${target}/sys"
if [[ -d "$TARGET/sys/firmware/efi/efivars" ]]; then if [[ -d "${target}/sys/firmware/efi/efivars" ]]; then
mount -t efivarfs efivarfs "$TARGET/sys/firmware/efi/efivars" mount -t efivarfs efivarfs "${target}/sys/firmware/efi/efivars"
fi fi
mount -o bind /dev "$TARGET/dev" mount -o bind /dev "${target}/dev"
mount -t devpts none "$TARGET/dev/pts" mount -t devpts none "${target}/dev/pts"
mount --bind /run "$TARGET/run" mount --bind /run "${target}/run"
linkresolv linkresolv
if [ -h $TARGET/dev/shm ]; then if [ -h "${target}/dev/shm" ]; then
mkdir -p $TARGET/$(readlink $TARGET/dev/shm) mkdir -p "${target}/$(readlink "${target}/dev/shm")"
else else
mount -t tmpfs -o nosuid,nodev tmpfs "$TARGET/dev/shm" mount -t tmpfs -o nosuid,nodev tmpfs "${target}/dev/shm"
fi fi
local prompt='\['$BOLD'\['$RED'(chroot)\['$RESET'\['$BOLD' \u@\h:\w#\['$RESET' ' local prompt='\['$BOLD'\['$RED'(chroot)\['$RESET'\['$BOLD' \u@\h:\w#\['$RESET' '
chroot "$TARGET" /usr/bin/env -i \ chroot "${target}" /usr/bin/env -i \
HOME=/root \ HOME=/root \
TERM="$TERM" \ TERM="${TERM}" \
PS1="$prompt" \ PS1="${prompt}" \
PATH=/usr/bin:/usr/sbin \ PATH=/usr/bin:/usr/sbin \
"$@" "$@"
RET_CODE=$? local ret_code=$?
# kill procs that may prevent umount # kill procs that may prevent umount
killall -9 dirmngr 2> /dev/null killall -9 dirmngr 2> /dev/null
killall -9 gpg-agent 2> /dev/null killall -9 gpg-agent 2> /dev/null
umount "$TARGET/proc" umount "${target}/proc"
mountpoint -q "$TARGET/sys/firmware/efi/efivars" && umount "$TARGET/sys/firmware/efi/efivars" mountpoint -q "${target}/sys/firmware/efi/efivars" && umount "${target}/sys/firmware/efi/efivars"
umount "$TARGET/sys" umount "${target}/sys"
umount "$TARGET/dev/pts" umount "${target}/dev/pts"
mountpoint -q "$TARGET/dev/shm" && umount "$TARGET/dev/shm" mountpoint -q "${target}/dev/shm" && umount "${target}/dev/shm"
umount "$TARGET/dev" umount "${target}/dev"
umount "$TARGET/run" umount "${target}/run"
return $ret_code
} }
################# #################
@ -84,24 +88,29 @@ chrt() {
################# #################
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
error "Cannot chroot without root" error "Cannot chroot without root"
exit 1
fi fi
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
error "Please specify a directory" error "Please specify a directory"
exit 1
fi fi
TARGET=$(realpath $1) target="$(realpath "${1}")"
if [ -f $TARGET ]; then
error "$TARGET is a file" if [ -f "${target}" ]; then
error "${target} is a file"
exit 1
fi fi
if [ ! -d $TARGET ]; then if [ ! -d "${target}" ]; then
error "$TARGET does not exist" error "${target} does not exist"
exit 1
fi fi
if [ $# -gt 1 ]; then if [ $# -gt 1 ]; then
chrt ${@:2} chrt ${@:2}
exit $RET_CODE exit $?
fi fi
chrt bash --noprofile --login chrt bash --noprofile --login

9
matter-iso/Makefile Normal file
View File

@ -0,0 +1,9 @@
PREFIX = /usr
install:
install -m755 "main.sh" $(DESTDIR)/$(PREFIX)/bin/matter-iso
uninstall:
rm $(DESTDIR)/$(PREFIX)/lib/matter-iso
.PHONY: install uninstall

View File

@ -8,4 +8,4 @@ a configuration directory:
``` ```
matter-iso matterlinux_24.00.tar.gz isocfg matter-iso matterlinux_24.00.tar.gz isocfg
``` ```
To learn more about the configuration, see the [wiki page for releases](/wiki/release). To learn more about the configuration, see the [wiki page for releases](/wiki/releases).

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# matter-iso | MatterLinux ISO Build Script # matter-iso | MatterLinux ISO build script
# MatterLinux 2023-2024 (https://matterlinux.xyz) # MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -16,71 +16,35 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
############################ #############################
## logging functions/vars ## ## import common functions ##
############################ #############################
BOLD="\e[1m" location="$(dirname "${0}")"
RESET="\e[0m" location="$(realpath "${location}")"
GREEN="\e[32m" commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
BLUE="\e[34m"
GRAY="\e[37m"
RED="\e[31m"
LOG_PREFIX=">>>"
echo_color() { source "${commonsh}"
echo -e "${1}"
}
success() { if [ "${?}" != "0" ]; then
echo_color "${BOLD}${GREEN}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}" echo "Failed to import mtsc-common"
}
info() {
echo_color "${BOLD}${BLUE}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
}
error() {
echo_color "${BOLD}${RED}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
exit 1 exit 1
} fi
errorne() {
echo_color "${BOLD}${RED}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
}
print() {
echo_color "${BOLD}${GRAY}$1${RESET}"
}
set_indent() {
LOG_PREFIX="|>"
}
unset_indent() {
LOG_PREFIX=">>>"
}
#################### ####################
## util functions ## ## util functions ##
#################### ####################
check_ret() {
if [ $? -ne 0 ]; then
error "$1"
fi
}
check_retc() { check_retc() {
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
errorne "$1" error "${1}"
clean_tmpdir clean_tmpdir
exit 1 exit 1
fi fi
} }
clean_tmpdir(){ clean_tmpdir(){
if [ -d $TMPDIR ]; then if [ -d "${tmpdir}" ]; then
info "Cleaning up temp directory" info "Cleaning up temp directory"
rm -rf $TMPDIR rm -rf "${tmpdir}"
fi fi
} }
@ -101,61 +65,71 @@ check_iso_vars() {
################# #################
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
error "You should run this script as root" error "You should run this script as root"
exit 1
fi fi
if [ $# -ne 2 ]; then if [ $# -ne 2 ]; then
error "Please specify a release archive and a config directory" error "Please specify a release archive and a config directory"
exit 1
fi fi
ARCHIVE="$(realpath $1)" archive="$(realpath "${1}")"
if [ ! -f $ARCHIVE ]; then
if [ ! -f "${archive}" ]; then
error "Archive file not found" error "Archive file not found"
exit 1
fi fi
if [[ "$(file $ARCHIVE)" != *"gzip compressed data"* ]]; then if [[ "$(file "${archive}")" != *"gzip compressed data"* ]]; then
error "Bad archive format" error "Bad archive format"
exit 1
fi fi
CONFDIR="$(realpath $2)" confdir="$(realpath "${2}")"
if [ ! -d $CONFDIR ]; then
if [ ! -d "${confdir}" ]; then
error "Config directory not found" error "Config directory not found"
exit 1
fi fi
TMPDIR="${CONFDIR}_tmp" tmpdir="${confdir}_tmp"
DISTDIR="${CONFDIR}/dist" distdir="${confdir}/dist"
ROOTDIR="${DISTDIR}/root" rootdir="${distdir}/root"
ISOSH="${TMPDIR}/iso.sh" isoh="${tmpdir}/iso.sh"
mkdir -p $ROOTDIR mkdir -p "${rootdir}"
success "Created root and dist directory" success "Created root and dist directory"
info "Copying over the config directory" info "Copying over the config directory"
cp -r $CONFDIR $TMPDIR cp -r "${confdir}" "${tmpdir}"
check_ret "Copy failed" check_ret "Copy failed"
if [ ! -f $ISOSH ]; then if [ ! -f "${isoh}" ]; then
error "ISO script not found" error "ISO script not found"
exit 1
fi fi
source $ISOSH source "${isoh}"
check_retc "Cannot source the ISO script" check_retc "Cannot source the ISO script"
check_iso_vars check_iso_vars
check_retc "ISO script is not valid" check_retc "ISO script is not valid"
success "Sourced the ISO script" success "Sourced the ISO script"
info "Removing excluded files" info "Removing excluded files"
rm -rf "$TMPDIR/dist" rm -rf "${tmpdir}/dist"
set_indent set_indent
for e in "${EXCLUDE[@]}"; do for e in "${EXCLUDE[@]}"; do
info "Removing $e" info "Removing ${e}"
rm -rf "$TMPDIR/$e" rm -rf "${tmpdir}/${e}"
done done
rm -rf "$TMPDIR/.git" rm -rf "${tmpdir}/.git"
unset_indent unset_indent
info "Extracting release archive" info "Extracting release archive"
SECONDS=0 SECONDS=0
tar --skip-old-files -xf "$ARCHIVE" -C "$TMPDIR"
tar --skip-old-files -xf "${archive}" -C "${tmpdir}"
check_retc "Extract failed" check_retc "Extract failed"
success "Extracted in ${SECONDS}s" success "Extracted in ${SECONDS}s"
@ -184,45 +158,45 @@ for p2 in "${PKGS2[@]}"; do
done done
info "Adding public keys" info "Adding public keys"
matter-chroot "$TMPDIR" gpg --receive-keys $keys_str matter-chroot "${tmpdir}" gpg --receive-keys $keys_str
check_retc "Failed to add public keys" check_retc "Failed to add public keys"
if [ ! -z "${PKGS1}" ]; then if [ ! -z "${PKGS1}" ]; then
info "Installing extra packages (1)" info "Installing extra packages (1)"
matter-chroot "$TMPDIR" mp-sync matter-chroot "${tmpdir}" matt sync
check_retc "Sync failed" check_retc "Sync failed"
matter-chroot "$TMPDIR" MP_YES=1 mp-install $pkgs1_str matter-chroot "${tmpdir}" matt install --yes $pkgs1_str
check_retc "Install failed" check_retc "Install failed"
fi fi
info "Running build script" info "Running build script"
echo "source /iso.sh && build" > "$TMPDIR/stager.sh" echo "source /iso.sh && build" > "${tmpdir}/stager.sh"
matter-chroot "$TMPDIR" chmod +x /stager.sh matter-chroot "${tmpdir}" chmod +x /stager.sh
matter-chroot "$TMPDIR" /stager.sh matter-chroot "${tmpdir}" /stager.sh
check_ret "Build script failed" check_ret "Build script failed"
rm "$TMPDIR/stager.sh" rm "${tmpdir}/stager.sh"
info "Cleaning up and building initrd" info "Cleaning up and building initrd"
rm "$ISOSH" rm "${isoh}"
pushd "$TMPDIR" > /dev/null pushd "$TMPDIR" > /dev/null
mkdir -p "$ROOTDIR/boot" mkdir -p "${rootdir}/boot"
find . | cpio --quiet -H newc -o | xz -T0 --check=crc32 > "$ROOTDIR/boot/initrd.img" find . | cpio --quiet -H newc -o | xz -T0 --check=crc32 > "${rootdir}/boot/initrd.img"
check_ret "Failed to build initrd" check_ret "Failed to build initrd"
popd > /dev/null popd > /dev/null
if [ ! -z "${PKGS2}" ]; then if [ ! -z "${PKGS2}" ]; then
info "Installing extra packages (2)" info "Installing extra packages (2)"
matter-chroot "$TMPDIR" MP_YES=1 mp-install $pkgs2_str matter-chroot "${tmpdir}" MP_YES=1 matt install --yes $pkgs2_str
check_ret "Install failed" check_ret "Install failed"
fi fi
info "Copying over the bootdir" info "Copying over the bootdir"
cp -r "$TMPDIR/boot"/* "$ROOTDIR/boot" cp -r "${tmpdir}/boot"/* "${rootdir}/boot"
info "Building the ISO..." info "Building the ISO..."
pushd "$DISTDIR" > /dev/null pushd "${distdir}" > /dev/null
grub-mkrescue -o "$DISTDIR/${NAME}_${VERSION}.iso" root grub-mkrescue -o "${distdir}/${NAME}_${VERSION}.iso" root
check_retc "grub-mkrescue failed" check_retc "grub-mkrescue failed"
popd > /dev/null popd > /dev/null

View File

@ -1 +0,0 @@
test/

View File

@ -1,14 +0,0 @@
# matter-mirror
A simple python script to create and manage MatterLinux mirrors.
**Does not support FTP!**
### Usage
To use the `matter-mirror` script, pass in a URL and a download (output)
directory. For example:
```bash
mkdir base
matter-mirror -u https://pkgs.matterlinux.xyz/base -o base
```
This will download the repo at `https://pkgs.matterlinux.xyz/base` to the
`base` directory. Running it again, script will only download outdated or
new packages.

View File

@ -1,262 +0,0 @@
#!/bin/python3
# matter-mirror | MatterLinux Repo Mirror Tool
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from os import path, chdir, listdir, remove
from typing import List
import requests as req
import logging as log
import configparser
import argparse
import tarfile
import hashlib
class BadResponse(Exception):
def __init__(self, msg: str) -> None:
super().__init__(f"Bad response: {msg}")
class Pkg:
def __init__(self, name: str, version: str, sum: str) -> None:
self.archive = f"{name}_{version}.mpf"
self.sig = f"{name}_{version}.mpf.sig"
self.version = version
self.name = name
self.sum = sum
def remove_old(self) -> None:
files = listdir(".")
for f in files:
if f.startswith(f"{self.name}_"):
remove(f)
class Repo:
def __init__(self, uri: str, out: str) -> None:
self.pkgs: List[Pkg] = []
self.author: str
self.name: str
self.pub: str
self.uri = uri
self.out = out
def join_url(self, pth: str) -> str:
if self.uri.endswith("/") and not pth.startswith("/"):
return self.uri+pth
elif self.uri.endswith("/") and pth.startswith("/"):
return self.uri[:-1]+pth
elif not self.uri.endswith("/") and pth.startswith("/"):
return self.uri+pth
return self.uri+"/"+pth
def get_repo(self) -> None:
repourl = self.join_url("repo")
res = req.get(repourl)
if res.status_code != 200:
raise BadResponse(f"{res.status_code} - {repourl}")
cfg = configparser.ConfigParser()
cfg.read_string(res.content.decode("utf-8"))
for k in cfg.keys():
if k == "DEFAULT":
continue
self.name = k
self.pub = cfg[self.name]["pub"]
self.author = cfg[self.name]["author"]
f = open("repo", "wb")
f.write(res.content)
f.close()
def process_pkgs(self, pkgs: str) -> None:
cfg = configparser.ConfigParser()
cfg.read_string(pkgs)
for k in cfg.keys():
try:
ver = cfg[k]["version"]
sum = cfg[k]["sum"]
except:
continue
self.pkgs.append(Pkg(k, ver, sum))
def check_pkg(self, pkg: Pkg) -> bool:
# true -> package is in the outdir and its up-to-date
# false -> its not ^
if not path.exists(pkg.archive) or not path.exists(pkg.sig):
return False
fhash = hashlib.sha256()
f = open(pkg.archive, "rb")
while chunk := f.read(8192):
fhash.update(chunk)
f.close()
if pkg.sum != fhash.hexdigest():
return False
return True
def check_pkgs(self) -> None:
pkgcl = []
for p in self.pkgs:
pkgcl.append(p)
for p in self.pkgs:
if self.check_pkg(p):
pkgcl.remove(p)
self.pkgs = pkgcl
def get_pkglist(self) -> None:
arcname = f"{self.name}.tar.gz"
pkgsurl = self.join_url(arcname)
res = req.get(pkgsurl)
if res.status_code != 200:
raise BadResponse(f"{res.status_code} - {pkgsurl}")
f = open(arcname, "wb")
f.write(res.content)
f.close()
t = tarfile.open(arcname)
for m in t.getmembers():
if m.name != "pkgs":
continue
f = t.extractfile(m)
if f == None: continue
self.process_pkgs(f.read().decode("utf-8"))
f.close()
t.close()
def download_pkg(self, p: Pkg) -> bool:
p.remove_old()
arcurl = self.join_url(p.archive)
sigurl = self.join_url(p.sig)
arcres = req.get(arcurl)
sigres = req.get(sigurl)
if arcres.status_code != 200:
raise BadResponse(f"{arcres.status_code} - {arcurl}")
if sigres.status_code != 200:
raise BadResponse(f"{sigres.status_code} - {sigurl}")
arcf = open(p.archive, "wb")
arcf.write(arcres.content)
arcf.close()
sigf = open(p.sig, "wb")
sigf.write(sigres.content)
sigf.close()
return True
if __name__ == "__main__":
log.basicConfig(
format="[%(levelname)s] [%(asctime)s]: %(message)s",
datefmt="%H:%M:%S",
level=log.INFO
)
parser = argparse.ArgumentParser(
prog="matter-mirror",
description="Create and manage MatterLinux mirrors",
epilog="Part of matter-tools | https://git.matterlinux.xyz/matter/matter-tools")
parser.add_argument("-u", help="Repo URI", required=True, dest="uri")
parser.add_argument("-o", help="Download directory", required=True, dest="out")
args = parser.parse_args()
if not args.uri.startswith("http://") and not args.uri.startswith("https://"):
log.error(f"Bad URI: {args.uri}")
exit(1)
if not path.exists(args.out):
log.error(f"Out directory not found: {args.out}")
exit(1)
if not path.isdir(args.out):
log.error(f"Out directory is not a directory: {args.out}")
exit(1)
try:
chdir(args.out)
except Exception as e:
log.error(f"Cannot change dir: {args.out}")
exit(1)
try:
repo = Repo(args.uri, args.out)
repo.get_repo()
except Exception as e:
log.error(e)
exit(1)
log.info(f"Got repo file => {repo.name}:{repo.author}:{repo.pub}")
log.info("Downloading package list")
try:
repo.get_pkglist()
except Exception as e:
log.error(e)
exit(1)
all = len(repo.pkgs)
if all == 0:
log.error("Got no valid packages!")
exit(1)
log.info(f"Got total of {all} packages")
try:
repo.check_pkgs()
except Exception as e:
log.error(e)
exit(1)
old = len(repo.pkgs)
if old == 0:
log.info("All packages are up-to-date!")
exit()
print(f" Up-to-date packages: {all-old} ({int(100*(all-old)/all)}%)")
print(f" New packages: {old} ({int(100*old/all)}%)")
resc = 0
for p in repo.pkgs:
try:
log.info(f"({repo.pkgs.index(p)+1}/{len(repo.pkgs)}) Downloading {p.name}")
try:
repo.download_pkg(p)
except KeyboardInterrupt:
log.error("Stopping downloads")
exit(1)
resc += 1
except Exception as e:
log.error(f"Download failed: {e}")
continue
log.info(f"Downloaded {resc} out of {old} packages ({int(100*resc/old)}%)")

16
mp-build/Makefile Normal file
View File

@ -0,0 +1,16 @@
SCRIPTS = $(patsubst scripts/%.sh,%,$(wildcard scripts/*.sh))
PREFIX = /usr
install:
@for s in $(SCRIPTS) ; do \
echo "installing script: $$s" ; \
install -m755 "scripts/$$s.sh" $(DESTDIR)/$(PREFIX)/bin/$$s ; \
done
uninstall:
@for s in $(SCRIPTS) ; do \
echo "removing script: $$s" ; \
rm $(DESTDIR)/$(PREFIX)/bin/$$s ; \
done
.PHONY: install uninstall

26
mp-build/README.md Normal file
View File

@ -0,0 +1,26 @@
# mp-build | MatterLinux package build scripts
The package build scripts for MatterLinux package system. These scripts
are used for building and creating packages.
### Usage
To create an package source directory, you can use the `mp-new`
script:
```bash
mp-new <name>_<version>
```
This will create all the required source files, all templated
according to the package name and the version you specify.
After editing the source files, you can build the package by
using the `mp-build` script:
```bash
mp-build /path/to/package
```
When the build is completed, the package archive will be created
inside the `/path/to/package/dist` directory.
You can also specify different build options, to list these
options you can run:
```bash
mp-build --help
```

452
mp-build/scripts/mp-build.sh Executable file
View File

@ -0,0 +1,452 @@
#!/bin/bash
# mp-build | MatterLinux package build script
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#############################
## import common functions ##
#############################
location="$(dirname "${0}")"
location="$(realpath "${location}")"
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}"
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
####################
## util functions ##
####################
# extracts the filename from an URL
get_fn_url() {
file=$(echo "${1}" | rev | cut -d "/" -f -1 | rev)
}
# download/copy file, used for obtaning $FILES
get_file() {
if [[ "${1}" == "https://"* || "${1}" == "http://"* || "${1}" == "ftp://"* ]]
then
curl "${1}" --progress-bar -OL
return $?
elif [ -f "${pkgpath}/${1}" ]; then
cp "${pkgpath}/${1}" .
return $?
else
return 1
fi
}
# length based hash check function
check_hash() {
if [[ "$2" == "NOHASH" ]]; then
info "Using NOHASH for $1"
return 0
fi
local len=${#2}
if [[ $len == 128 ]]; then
local hsh=$(sha512sum "$1" | cut -d " " -f 1)
elif [[ $len == 64 ]]; then
local hsh=$(sha256sum "$1" | cut -d " " -f 1)
elif [[ $len == 64 ]]; then
local hsh=$(sha256sum "$1" | cut -d " " -f 1)
elif [[ $len == 40 ]]; then
local hsh=$(sha1sum "$1" | cut -d " " -f 1)
elif [[ $len == 32 ]]; then
local hsh=$(md5sum "$1" | cut -d " " -f 1)
fi
if [[ "$hsh" == "$2" ]]; then
success "Hash matches for $1"
return 0
else
error "Bad hash for $1"
return 1
fi
}
# prints the help info
help_cmd() {
info "MatterLinux package build script"
info "Usage: ${0} <options> [package directory]"
info "Options:"
echo_color " $BOLD--no-depend$RESET: don't check depends"
echo_color " $BOLD--no-stdout$RESET: disable stdout for PACKAGE() function"
echo_color " $BOLD--no-cache$RESET: don't check cache"
echo_color " $BOLD--no-opts$RESET: don't show/list options"
echo_color " $BOLD--cores$RESET: how many cores to use for the build"
echo
info "Licensed under GPLv3, see <https://www.gnu.org/licenses/> for more information"
}
# clean the this directory
clean_dist() {
rm -f "${distpath}/DATA"
rm -f "${distpath}/CHANGES"
rm -f "${distpath}/INSTALL"
rm -f "${distpath}/HASHES"
rm -f "${distpath}/files.tar.gz"
}
# checks/installs a list of depends
check_depends() {
local list=("$@")
if [ "${#list[@]}" == "0" ]; then
info "Got zero depends, skipping depend check"
return 0
fi
if [ "$EUID" -ne 0 ]; then
if type doas > /dev/null; then
DOAS="doas"
elif type sudo > /dev/null; then
DOAS="sudo"
else
error "Failed to find doas or sudo, skipping depend check"
return 0
fi
fi
for dep in "${list[@]}"; do
if [ -z "${depends_str}" ]; then
depends_str="${dep}"
else
depends_str="${depends_str} ${dep}"
fi
done
depends_uniq=$(echo "${depends_str}" | tr ' ' '\n' | sort | uniq)
depends_count=$(echo "${depends_uniq}" | wc -l)
depends_uniq=$(echo "${depends_uniq}" | tr '\n' ' ')
info "Installing ${depends_count} depends"
$DOAS matt install --yes $depends_uniq
return $?
}
#################
## main script ##
#################
OPT_NO_DEPEND=0 # checking depends is ENABLED
OPT_NO_STDOUT=0 # PACKAGE() function output is ENABLED
OPT_NO_CACHE=0 # cache is ENABLED
OPT_NO_OPTS=0 # showing/listing options is ENABLED
OPT_CORES=$(nproc) # use ALL CPU cores
# parses all the options
for arg in "$@"; do
case $arg in
"--help")
help_cmd
exit 0
;;
"--no-depend")
OPT_NO_DEPEND=1 ;;
"--no-stdout")
OPT_NO_STDOUT=1 ;;
"--no-cache")
OPT_NO_CACHE=1 ;;
"--no-opts")
OPT_NO_OPTS=1 ;;
"--cores"*)
OPT_CORES=$(echo "${arg}" | cut -d "=" -f2) ;;
--*)
error "Unknown option: ${arg}"
exit 1 ;;
*)
if [ -z "${TARGET}" ]; then
TARGET="${arg}"
else
error "Unknown argument: ${arg}"
exit 1
fi
;;
esac
done
if [ -z "${TARGET}" ]; then
error "Package directory is not specified, run with \"--help\" for more information"
exit 1
fi
if [ ! -d "${TARGET}" ]; then
error "Package directory \"${TARGET}\" does not exist"
exit 1
fi
if [ $OPT_NO_DEPEND -eq 0 ] && ! command -v matt &> /dev/null; then
error "!!! BUILD ON MATTERLINUX !!!"
error "matt is not installed, please build on a MatterLinux system"
error "Do NOT create bug reports if build fails on non-MatterLinux systems"
info "Auto enabling NO_DEPEND as depend check will fail without matt"
OPT_NO_DEPEND=1
fi
# print the options
if [ $OPT_NO_OPTS -eq 0 ]; then
info "Running mp-build with the options:"
print " $BOLD NO_DEPEND = $(itoyn $OPT_NO_DEPEND)"
print " $BOLD NO_SDTOUT = $(itoyn $OPT_NO_STDOUT)"
print " $BOLD NO_CACHE = $(itoyn $OPT_NO_CACHE)"
print " $BOLD NO_OPTS = $(itoyn $OPT_NO_OPTS)"
print " $BOLD CORES = $OPT_CORES"
fi
cd "${TARGET}"
check_ret "Failed to change directory into \"${TARGET}\""
if [ ! -f "pkg.sh" ]; then
error "Package directory does not contain a package script (pkg.sh)"
exit 1
fi
# source and verify the package script
source "pkg.sh"
check_ret "Failed to source the package script"
check_pkg_vars
check_ret
# check the changes file
if [ ! -f "changes.md" ]; then
warn "Package directory does not contain a changes file (changes.md)"
warn "Creating an empty one, however you should you should create an actual changes file"
echo "# ${VERSION}" > "changes.md"
echo "No changes specified" >> "changes.md"
fi
# setup package directories
pkgpath="$(realpath .)"
cachepath="$(realpath '.cache')"
distpath="$(realpath 'dist')"
rootpath="$(realpath 'root')"
mkdir -p "${rootpath}"
check_ret "Failed to create the root directory"
# check the cache
package_hash=$(md5sum "${pkgpath}/pkg.sh" 2> /dev/null | awk '{print $1}')
changes_hash=$(md5sum "${pkgpath}/changes.md" 2> /dev/null | awk '{print $1}')
if [ $OPT_NO_CACHE -eq 0 ] && [ -f "${cachepath}/last" ]; then
package_cache=$(sed -n '1p' "${cachepath}/last")
changes_cache=$(sed -n '2p' "${cachepath}/last")
if [[ "${package_cache}" == "${package_hash}" ]] && [[ "${changes_cache}" == "${changes_hash}" ]]; then
info "Found build in the cache (add --no-cache if you want to rebuild anyway)"
success "Build was successful"
exit 0
fi
fi
# check all the depends for the build
all_depends+=("${DEPENDS[@]}")
all_depends+=("${BUILD[@]}")
if [ $OPT_NO_DEPEND -eq 0 ]; then
check_depends "${all_depends[@]}"
check_ret "Failed to check all the dependencies"
fi
# make sure file count and the hash count is the same
file_count=${#FILES[@]}
hash_count=${#HASHES[@]}
if [[ $file_count != $hash_count ]]; then
error "There are ${file_count} files but ${hash_count} hashes"
exit 1
fi
# cleanup files from previous builds
info "Cleaning up files from the previous build"
set_indent
for f in "${rootpath}"/*; do
# do not remove the file if its required for build
for ((i = 0; i < $file_count; i++)) do
get_fn_url "${FILES[i]}"
if [[ "$(realpath "${rootpath}/${file}")" == "$(realpath ${f})" ]]; then
isdownload=1
break
fi
done
if [ -z $isdownload ]; then
info "Removing file from previous build: $f"
rm -rf "$f"
fi
unset isdownload
done
unset_indent
cd "${rootpath}"
check_ret "Failed to change directory into the root directory"
info "Obtaining all the files"
set_indent
for ((i = 0; i < $file_count; i++)) do
get_fn_url "${FILES[i]}"
# check if the file is already present
if [ -f "$file" ]; then
check_hash $file ${HASHES[i]} > /dev/null
if [ $? -eq 0 ]; then
success "($(($i+1))/$file_count) Using the file from previous build: $file"
continue
fi
rm -f $file
fi
info "($(($i+1))/$file_count) Obtaining file: $file"
get_file ${FILES[i]}
check_ret "Failed to obtain the file!"
check_hash "${file}" ${HASHES[i]}
check_ret "Verification failed for file: $file"
done
unset_indent
info "Running the build function"
export CFLAGS="-march=x86-64 -mtune=generic -O2"
export ROOTDIR="${rootpath}"
export MAKEFLAGS="-j${OPT_CORES}"
export MAKEOPTS="-j${OPT_CORES}"
export XORG_PREFIX="/usr"
export XORG_CONFIG="--prefix=${XORG_PREFIX} --sysconfdir=/etc \
--localstatedir=/var --disable-static"
SECONDS=0
if [ $OPT_NO_STDOUT -eq 0 ]; then
fakeroot "${location}/mp-wrap" "../pkg.sh"
check_ret "Package PACKAGE() function failed"
else
fakeroot "${location}/mp-wrap" "../pkg.sh" > /dev/null
check_ret "Package PACKAGE() function failed"
fi
unset XORG_CONFIG XORG_PREFIX
unset CFLAGS ROOTDIR
unset MAKEOPTS MAKEFLAGS
if [ "$SECONDS" != "0" ]; then
success "Completed the build in ${SECONDS}s"
else
success "Completed the build in less than a second"
fi
# remove all the $FILES
for ((i = 0; i < $file_count; i++)) do
get_fn_url ${FILES[i]} && rm -f $file
success "Removed file: $file"
done
info "Building the package archive"
set_indent
# cleanup the dist directory
mkdir -p "${distpath}"
clean_dist
# build the files archive
find . -printf "%P\n" | fakeroot tar -czf "${distpath}/files.tar.gz" --no-recursion -T -
check_ret "(1/6) Failed to create the files archive (files.tar.gz)"
success "(1/6) Created the files archive (files.tar.gz)"
# build the DATA file
cat > "${distpath}/DATA" << EOF
[${NAME}]
version = ${VERSION}
desc = ${DESC}
size = $(du -sb "${rootpath}" | awk '{print $1}')
EOF
for dep in "${DEPENDS[@]}"; do
echo "depends = ${dep}" >> "${distpath}/DATA"
done
for keep in "${KEEP[@]}"; do
echo "keep = ${keep}" >> "${distpath}/DATA"
done
success "(2/6) Created the package data file (DATA)"
# create the changes file
cp "${pkgpath}/changes.md" "${distpath}/CHANGES"
check_ret "(3/6) Failed to create the changes file (CHANGES)"
success "(3/6) Created the changes file (CHANGES)"
# create the install script
if type INSTALL &>/dev/null; then
echo "$(type INSTALL | tail -n+2)" > "${distpath}/INSTALL"
check_ret "(4/6) Failed to create the install script (INSTALL)"
fi
success "(4/6) Created the install script (INSTALL)"
# create the HASHES file
find . -type f -exec md5sum {} >> "${distpath}/HASHES" \;
check_ret "(5/6) Failed to create the file hash list (HASHES)"
success "(5/6) Created the file hash list (HASHES)"
# remove previous build archives
for old in "${distpath}/${NAME}_"*.mpf; do
rm -f $old
done
# create the final archive
archive="${NAME}_${VERSION}.mpf"
pushd "${distpath}" > /dev/null
find . -printf "%P\n" | fakeroot tar -czf "${archive}" --no-recursion -T -
check_ret "(6/6) Failed to create the package archive (${archive})"
popd > /dev/null
success "(6/6) Created the package archive (${archive})"
# clean up
cd "${pkgpath}"
info "Cleaning up the dist directory"
clean_dist
info "Cleaning the root directory"
rm -rf "${rootpath}"
# update the cache
unset_indent
info "Updating the package cache"
set_indent
mkdir -p "${cachepath}"
echo "${package_hash}" > "${cachepath}/last"
check_ret "(1/2) Failed to add package script to the cache"
success "(1/2) Added package script to the cache"
echo "${changes_hash}" >> "${cachepath}/last"
check_ret "(2/2) Failed to add changes file to the cache"
success "(2/2) Added changes file to the cache"
unset_indent
success "Build was successful"
exit 0

94
mp-build/scripts/mp-migrate.sh Executable file
View File

@ -0,0 +1,94 @@
#!/bin/bash
# mp-migrate | MatterLinux package migration script
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#############################
## import common functions ##
#############################
location="$(dirname "${0}")"
location="$(realpath "${location}")"
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}"
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
#################
## main script ##
#################
if [ -z "$1" ]; then
error "Please specify a package directory"
exit 1
fi
if [ ! -d "$1" ]; then
error "Failed to access to the specified directory"
exit 1
fi
target="$(realpath "${1}")"
pkg_script="${target}/pkg.sh"
install_script="${target}/install.sh"
if [ ! -f "${pkg_script}" ]; then
error "Specified directory does not contain a package script (pkg.sh)"
exit 1
fi
info "Sourcing the package script"
source "${pkg_script}"
if [ -z "${VERSION}" ]; then
error "Required package variable \"\$VERSION\" is not set"
exit 1
fi
info "Auto generating the changes file"
cat > "${target}/changes.md" << EOF
# ${VERSION}
First version
EOF
info "Adding the gitignore file"
cat > "${target}/.gitignore" << EOF
.cache/
dist/
root/
EOF
sed -i 's/build() {/PACKAGE() {/' "${pkg_script}"
check_ret "Failed to update the build function"
if [ -f "${install_script}" ]; then
info "Migrating the install script"
echo >> "${pkg_script}"
echo "INSTALL(){" >> "${pkg_script}"
while read l; do
echo " ${l}" >> "${pkg_script}"
done < "${install_script}"
echo "}" >> "${pkg_script}"
rm "${install_script}"
check_ret "Failed to remove the install script"
fi
success "Migration is completed"

108
mp-build/scripts/mp-new.sh Executable file
View File

@ -0,0 +1,108 @@
#!/bin/bash
# mp-new | MatterLinux package creation script
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#############################
## import common functions ##
#############################
location="$(dirname "${0}")"
location="$(realpath "${location}")"
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}"
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
#################
## main script ##
#################
if [ -z "$1" ]; then
error "Please specify a package"
exit 1
fi
pkg=$(basename "${1}")
target=$(dirname "${1}")
case "${1}" in
*_*)
name=$(echo "${pkg}" | cut -d "_" -f1)
version=$(echo "${pkg}" | cut -d "_" -f2)
;;
*)
warn "Package version is not specified, using \"1\" as version instead"
name="${pkg}"
version="1"
;;
esac
if [ -d "${target}/${name}" ]; then
error "There is already a directory for \"${target}/${name}\""
exit 1
fi
info "Creating directory for \"${name}\""
mkdir "${target}/${name}"
check_ret "Failed to create package directory for \"${name}\""
cd "${target}/${name}"
cat > pkg.sh << EOF
# general info
NAME="${name}"
DESC=""
VERSION="${version}"
# required files
FILES=()
HASHES=()
# install and build depends
DEPENDS=()
BUILD=()
PACKAGE(){
tar xf "\${NAME}-\${VERSION}.tar.gz"
cd "\${NAME}-\${VERSION}"
# build commands
cd .. && rm -r "\${NAME}-\${VERSION}"
}
INSTALL(){
# install script
# remove if not requied
}
EOF
cat > changes.md << EOF
# ${version}
First version
EOF
cat > .gitignore << EOF
.cache/
dist/
root/
EOF
success "Created package directory and files for \"${name}\""

56
mp-build/scripts/mp-wrap.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/bash
# mp-wrap | MatterLinux package build function wrapper
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#############################
## import common functions ##
#############################
location="$(dirname "${0}")"
location="$(realpath "${location}")"
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}"
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
#################
## main script ##
#################
if [ -z "${1}" ]; then
error "Package script not specified"
exit 1
fi
ninja(){
echo "[ninja wrapper] adding MAKEFLAGS"
/usr/bin/ninja $MAKEFLAGS $@
}
echo "running the PACKAGE() function"
set -e
source "${1}"
PACKAGE
ret="$?"
set +e
echo "PACKAGE() returned with code $ret"
exit $ret

16
mp-pool/Makefile Normal file
View File

@ -0,0 +1,16 @@
SCRIPTS = $(patsubst scripts/%.sh,%,$(wildcard scripts/*.sh))
PREFIX = /usr
install:
@for s in $(SCRIPTS) ; do \
echo "installing script: $$s" ; \
install -m755 "scripts/$$s.sh" $(DESTDIR)/$(PREFIX)/bin/$$s ; \
done
uninstall:
@for s in $(SCRIPTS) ; do \
echo "removing script: $$s" ; \
rm $(DESTDIR)/$(PREFIX)/bin/$$s ; \
done
.PHONY: install uninstall

12
mp-pool/README.md Normal file
View File

@ -0,0 +1,12 @@
# mp-pool | MatterLinux pool build scripts
The pool build scripts for MatterLinux package system. These scripts
are used for building and creating pools.
### Usage
To build a pool from the source, you can use the `mp-pool`
script:
```bash
mp-pool /path/to/pool
```
When the build is completed, the package archives and pool files
will be created inside the `/path/to/pool/dist` directory.

126
mp-pool/scripts/mp-pool-clean.sh Executable file
View File

@ -0,0 +1,126 @@
#!/bin/bash
# mp-pool-clean | MatterLinux pool cleanup script
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#############################
## import common functions ##
#############################
location=$(dirname "${0}")
location=$(realpath "${location}")
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}" > /dev/null
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
#################
## main script ##
#################
target="${1}"
if [ -z "${target}" ]; then
error "Please specify a pool directory"
exit 1
fi
if [ ! -d "${target}" ]; then
error "Pool directory \"${target}\" does not exist"
exit 1
fi
cd "${target}"
check_ret "Failed to change directory into \"${target}\""
if [ ! -f "pool.sh" ]; then
error "Package directory does not contain a pool script (pool.sh)"
exit 1
fi
# source and verify the package script
source "pool.sh"
check_ret "Failed to source the pool script"
check_pool_vars
check_ret
# setup package directories
pkgpath="$(realpath .)"
distpath="$(realpath 'dist')"
srcpath="$(realpath "${SRCDIR}")"
if [ ! -d "${srcpath}" ]; then
error "Source path does not exist"
exit 1
fi
if [ ! -d "${distpath}" ]; then
info "Nothing to do (dist directory does not exist)"
exit 1
fi
# source and store every package
files=("INFO" "LIST")
pc="$(ls -1q "${srcpath}" | wc -l)"
pi=1
info "Sourcing all the packages"
set_indent
for pkg in "${srcpath}/"*; do
package=$(basename "${pkg}")
info "(${pi}/${pc}) Sourcing \"${package}\""
source "${pkg}/pkg.sh"
check_ret "(${pi}/${pc}) Failed to import the source script for \"${package}\""
check_pkg_vars
check_ret
files+=("${NAME}_${VERSION}.mpf")
files+=("${NAME}_${VERSION}.mpf.sig")
pi=$((pi+1))
done
success "Completed"
unset_indent
info "Cleaning up old archives and signatures"
pushd "${distpath}" > /dev/null
set_indent
for file in *; do
found=0
for f in "${files[@]}"; do
if [ "${file}" == "${f}" ]; then
found=1
break
fi
done
if [ $found -eq 0 ]; then
info "Removing ${file}"
rm "${file}"
check_ret "Failed to remove ${file}"
fi
done
popd > /dev/null
success "Completed"
unset_indent

293
mp-pool/scripts/mp-pool.sh Executable file
View File

@ -0,0 +1,293 @@
#!/bin/bash
# mp-pool | MatterLinux pool build script
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#############################
## import common functions ##
#############################
location=$(dirname "${0}")
location=$(realpath "${location}")
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}" > /dev/null
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
####################
## util functions ##
####################
# prints the help info
help_cmd() {
info "MatterLinux pool build script"
info "Usage: ${0} <options> [pool directory]"
info "Options:"
echo_color " $BOLD--skip-fail$RESET: skip if a package build fails"
echo_color " $BOLD--no-depend$RESET: don't check depends"
echo_color " $BOLD--no-stdout$RESET: disable stdout for build() function"
echo_color " $BOLD--no-cache$RESET: don't use cache"
echo_color " $BOLD--no-opts$RESET: don't show/list options"
echo_color " $BOLD--no-sign$RESET: don't sign build packages"
echo_color " $BOLD--cores$RESET: how many cores to use for the build"
echo
info "Licensed under GPLv3, see <https://www.gnu.org/licenses/> for more information"
}
# clean the dist directory
clean_dist() {
rm -f "${distpath}/DATA"
rm -f "${distpath}/CHANGES"
rm -f "${distpath}/INSTALL"
rm -f "${distpath}/HASHES"
rm -f "${distpath}/files.tar.gz"
}
# convert bash array to newline splitted string
list_to_str(){
local list=("$@")
for el in "${list[@]}"; do
if [ -z "${str}" ]; then
str="${el}"
else
printf -v str "${str}\n ${el}"
fi
done
}
# run mp-build with options
mp_build_opts(){
local opts=("${1}" "--no-opts")
if [ $OPT_NO_DEPEND -eq 1 ]; then
opts+=("--no-depend")
fi
if [ $OPT_NO_STDOUT -eq 1 ]; then
opts+=("--no-stdout")
fi
if [ $OPT_NO_CACHE -eq 1 ]; then
opts+=("--no-cache")
fi
mp-build ${opts[@]}
return "$?"
}
#################
## main script ##
#################
OPT_SKIP_FAIL=0 # stop build when a package build fails
OPT_NO_DEPEND=0 # checking depends is ENABLED
OPT_NO_STDOUT=0 # build() function output is ENABLED
OPT_NO_CACHE=0 # cache is ENABLED
OPT_NO_OPTS=0 # showing/listing options is ENABLED
OPT_NO_SIGN=0 # sign all the built packages
OPT_CORES=$(nproc) # use ALL CPU cores
# parses all the options
for arg in "$@"; do
case $arg in
"--help")
help_cmd
exit 0
;;
"--skip-fail")
OPT_SKIP_FAIL=1 ;;
"--no-depend")
OPT_NO_DEPEND=1 ;;
"--no-stdout")
OPT_NO_STDOUT=1 ;;
"--no-cache")
OPT_NO_CACHE=1 ;;
"--no-opts")
OPT_NO_OPTS=1 ;;
"--no-sign")
OPT_NO_SIGN=1 ;;
"--cores"*)
OPT_CORES=$(echo "${arg}" | cut -d "=" -f2) ;;
--*)
error "Unknown option: ${arg}"
exit 1 ;;
*)
if [ -z "${TARGET}" ]; then
TARGET="${arg}"
else
error "Unknown argument: ${arg}"
exit 1
fi
;;
esac
done
if [ -z "${TARGET}" ]; then
error "Pool directory is not specified, run with \"--help\" for more information"
exit 1
fi
if [ ! -d "${TARGET}" ]; then
error "Pool directory \"${TARGET}\" does not exist"
exit 1
fi
if [ $OPT_NO_DEPEND -eq 0 ] && ! command -v matt &> /dev/null; then
error "!!! BUILD ON MATTERLINUX !!!"
error "matt is not installed, please build on a MatterLinux system"
error "Do NOT create bug reports if build fails on non-MatterLinux systems"
info "Auto enabling NO_DEPEND as depend check will fail without mp"
OPT_NO_DEPEND=1
fi
# print the options
if [ $OPT_NO_OPTS -eq 0 ]; then
info "Running mp-pool with the options:"
print " $BOLD SKIP_FAIL = $(itoyn $OPT_SKIP_FAIL)"
print " $BOLD NO_DEPEND = $(itoyn $OPT_NO_DEPEND)"
print " $BOLD NO_SDTOUT = $(itoyn $OPT_NO_STDOUT)"
print " $BOLD NO_CACHE = $(itoyn $OPT_NO_CACHE)"
print " $BOLD NO_OPTS = $(itoyn $OPT_NO_OPTS)"
print " $BOLD NO_SIGN = $(itoyn $OPT_NO_SIGN)"
print " $BOLD CORES = $OPT_CORES"
fi
cd "${TARGET}"
check_ret "Failed to change directory into \"${TARGET}\""
if [ ! -f "pool.sh" ]; then
error "Package directory does not contain a pool script (pool.sh)"
exit 1
fi
# source and verify the package script
source "pool.sh"
check_ret "Failed to source the pool script"
check_pool_vars
check_ret
# setup package directories
pkgpath="$(realpath .)"
distpath="$(realpath 'dist')"
srcpath="$(realpath "${SRCDIR}")"
mkdir -p "${distpath}"
check_ret "Failed to create the dist directory"
if [ ! -d "${srcpath}" ]; then
error "Source path does not exist"
exit 1
fi
# build every package
pc="$(ls -1q "${srcpath}" | wc -l)"
pi=1
for pkg in "${srcpath}/"*; do
package=$(basename "${pkg}")
info "(${pi}/${pc}) Building \"${package}\""
if [ $OPT_SKIP_FAIL -eq 1 ]; then
mp_build_opts "${pkg}"
if [ $? -ne "0" ]; then
error "(${pi}/${pc}) Build failed for \"${package}\", skipping"
pi=$((pi+1))
continue
fi
else
mp_build_opts "${pkg}"
check_ret "(${pi}/${pc}) Build failed for \"${package}\""
fi
archive="$(find "${pkg}/dist" -name "*.mpf" | tail -n1)"
name="$(echo "${archive}" | cut -d _ -f 1)"
if [ ! -z "${archive}" ]; then
rm -f "${distpath}/${name}_"*
mv "${archive}" "${distpath}"
check_ret "(${pi}/${pc}) Moving package archive failed for \"${package}\""
fi
success "(${pi}/${pc}) Build was successful for \"${package}\""
pi=$((pi+1))
done
success "Completed all the package builds"
# sign packages
if [ "$OPT_NO_SIGN" -eq 0 ]; then
gpg --list-secret-keys "${PUBKEY}" &> /dev/null
check_ret "Package signing is enabled, however you do not have the required private key"
info "Signing package archives"
set_indent
for pkg in "${distpath}/"*".mpf"; do
gpg --default-key "${PUBKEY}" --yes --detach-sign "${pkg}" &> /dev/null
check_ret "Failed to sign package archive: \"$(basename "${pkg}")\""
success "Signed archive: $(basename "${pkg}")"
done
success "Signing process was completed"
unset_indent
fi
info "Creating pool files"
set_indent
# create INFO file
cat > "${distpath}/INFO" << EOF
[${NAME}]
size = $(du -sb "${distpath}" | awk '{print $1}')
maintainer = ${MAINTAINER}
pubkey = ${PUBKEY}
EOF
check_ret "(1/2) Failed to create pool info file (INFO)"
success "(1/2) Created pool info file (INFO)"
# create LIST archive
rm -rf "${distpath}/list"
mkdir -p "${distpath}/list"
cd "${distpath}/list"
check_ret "Failed change directory into temporary list directory"
info "Creating package list archive"
for pkg in "${distpath}/"*".mpf"; do
archive="$(basename "${pkg}")"
name="${archive::-4}"
mkdir "${name}"
check_ret "Failed to create list directory for \"${archive}\", is there two packages with the same name?"
tar xf "${pkg}" -C "${name}" DATA
check_ret "Failed to extract data file from \"${archive}\""
done
pushd "${distpath}/list" > /dev/null
tar czf "${distpath}/LIST" *
check_ret "(2/2) Failed to create list archive (LIST)"
popd > /dev/null
rm -r "${distpath}/list"
check_ret "(2/2) Failed to remove temporary list directory"
success "(2/2) Created package list archive (LIST)"
unset_indent
success "Pool build was successful"

9
mtsc-common/Makefile Normal file
View File

@ -0,0 +1,9 @@
PREFIX = /usr
install:
install -m755 "common.sh" $(DESTDIR)/$(PREFIX)/lib/mtsc-common.sh
uninstall:
rm $(DESTDIR)/$(PREFIX)/lib/mtsc-common.sh
.PHONY: install uninstall

3
mtsc-common/README.md Normal file
View File

@ -0,0 +1,3 @@
# mtsc-common | MatterLinux common script functions
A (bash) shell script that contains common functions used in MatterLinux
build scripts and tools.

206
mtsc-common/common.sh Executable file
View File

@ -0,0 +1,206 @@
#!/bin/bash
# mtsc-common | MatterLinux common script functions
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
$(return 0 2>/dev/null)
if [ $? -eq 1 ]; then
echo "This script contains common functions for MatterLinux tools/scripts"
echo "You are not supposed to directly run it, now exiting to prevent any errors"
exit 1
fi
############################
## logging functions/vars ##
############################
BOLD="\e[1m"
RESET="\e[0m"
YELLOW="\e[33m"
GREEN="\e[32m"
BLUE="\e[34m"
GRAY="\e[37m"
RED="\e[31m"
NORMAL_PREFIX=">>>"
INDENT_PREFIX=" |"
LOG_PREFIX="$NORMAL_PREFIX"
echo_color() {
echo -e "${1}"
}
success() {
if [ "$LOG_PREFIX" == "$NORMAL_PREFIX" ]; then
echo_color "${BOLD}${GREEN}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
else
echo_color "${BOLD}${GREEN}${LOG_PREFIX}${RESET} $1"
fi
}
info() {
if [ "$LOG_PREFIX" == "$NORMAL_PREFIX" ]; then
echo_color "${BOLD}${BLUE}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
else
echo_color "${BOLD}${BLUE}${LOG_PREFIX}${RESET} $1"
fi
}
warn() {
if [ "$LOG_PREFIX" == "$NORMAL_PREFIX" ]; then
echo_color "${BOLD}${YELLOW}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
else
echo_color "${BOLD}${YELLOW}${LOG_PREFIX}${RESET} $1"
fi
}
error() {
if [ "$LOG_PREFIX" == "$NORMAL_PREFIX" ]; then
echo_color "${BOLD}${RED}${LOG_PREFIX}${RESET}${BOLD} $1 ${RESET}"
else
echo_color "${BOLD}${RED}${LOG_PREFIX}${RESET} $1"
fi
}
print() {
echo_color "${BOLD}${GRAY}$1${RESET}"
}
set_indent() {
LOG_PREFIX="$INDENT_PREFIX"
}
unset_indent() {
LOG_PREFIX="$NORMAL_PREFIX"
}
####################
## util functions ##
####################
check_ret() {
if [ $? -ne 0 ]; then
if [ ! -z "$1" ]; then
error "$1"
fi
exit 1
fi
}
# integer-to-yes-or-no
itoyn() {
if [ $1 -eq 0 ]; then
echo "${RED}no${RESET}"
else
echo "${GREEN}yes${RESET}"
fi
}
# checks if all the required package vars/functions are set
check_pool_vars() {
if [ ! -n "$NAME" ]; then
error "Failed to load the pool script"
set_indent
error "Required pool variable is not set: \"\$NAME\""
unset_indent
return 1
elif [ ! -n "$MAINTAINER" ]; then
error "Failed to load the pool script"
set_indent
error "Required pool variable is not set: \"\$MAINTAINER\""
unset_indent
return 1
elif [ ! -n "$PUBKEY" ]; then
error "Failed to load the pool script"
set_indent
error "Required pool variable is not set: \"\$PUBKEY\""
unset_indent
return 1
elif [ ! -n "$SRCDIR" ]; then
error "Failed to load the pool script"
set_indent
error "Required pool variable is not set: \"\$SRCDIR\""
unset_indent
return 1
fi
case "${NAME}" in
*" "*)
error "Pool name contains an invalid character: \" \""
unset_indent
return 1 ;;
esac
return 0
}
# checks if all the required package vars/functions are set
check_pkg_vars() {
if [ ! -n "$NAME" ]; then
error "Failed to load the package script"
set_indent
error "Required package variable is not set: \"\$NAME\""
unset_indent
return 1
elif [ ! -n "$VERSION" ]; then
error "Failed to load the package script"
set_indent
error "Required package variable is not set: \"\$VERSION\""
unset_indent
return 1
elif [ ! -n "$DESC" ]; then
error "Failed to load the package script"
set_indent
error "Required package variable is not set: \"\$DESC\""
unset_indent
return 1
elif ! type PACKAGE &>/dev/null; then
error "Failed to load the package script"
set_indent
error "Required \"PACKAGE()\" function is not defined"
unset_indent
return 1
fi
case "${NAME}" in
*_*)
error "Package name contains an invalid character: \"_\""
unset_indent
return 1 ;;
*" "*)
error "Package name contains an invalid character: \" \""
unset_indent
return 1 ;;
esac
return 0
}