mirror of
https://codeberg.org/hyperreal/vauxite-build
synced 2024-11-25 12:23:42 +01:00
Refactor; add sign_commit()
This commit is contained in:
parent
d3066bf6a5
commit
ca05f01dd6
152
ostree-engine
152
ostree-engine
@ -1,19 +1,42 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
"""ostree-engine
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
ostree-engine ([--source-branch=BRANCH] [--source-url=URL] | --no-download-sources)
|
||||||
|
[--ostree-branch=REF] [--treefile=TREEFILE]
|
||||||
|
[--dest-repo=PATH] [--gpg-passfile=PATH]
|
||||||
|
[--no-deploy] [--no-clean]
|
||||||
|
ostree-engine --version
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--no-deploy Do not deploy resulting ostree repo to web server root.
|
||||||
|
--no-clean Do not clean the working directory, i.e. .cache, .build-repo, .source-repo, .tmp
|
||||||
|
--no-download-sources Do not download source repo.
|
||||||
|
--source-url=URL URL for source repo. [default: https://pagure.io/workstation-ostree-config]
|
||||||
|
--source-branch=BRANCH Branch of the source repo.
|
||||||
|
--treefile=TREEFILE YAML or JSON treefile to use for rpm-ostree.
|
||||||
|
--ostree-branch=REF Name of the ref branch.
|
||||||
|
--dest-repo=PATH Local or remote filesystem destination for rsync-repos. Usually a web server root. [default: /srv/repo]
|
||||||
|
--gpg-passfile=PATH Path to JSON file containing GPG key-id and passphrase (for auto signing commits).
|
||||||
|
--version Print version information.
|
||||||
|
"""
|
||||||
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from docopt import docopt
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
exit("Please run this script with sudo")
|
exit("Please run this script with sudo")
|
||||||
|
|
||||||
BASE_DIR = Path("/home/jas/vauxite")
|
BASE_DIR = Path("/var/local/vauxite")
|
||||||
OSTREE_FILES_DIR = BASE_DIR.joinpath("src")
|
OSTREE_FILES_DIR = BASE_DIR.joinpath("src")
|
||||||
CACHE_DIR = BASE_DIR.joinpath(".cache")
|
CACHE_DIR = BASE_DIR.joinpath(".cache")
|
||||||
BUILD_REPO = BASE_DIR.joinpath(".build-repo")
|
BUILD_REPO = BASE_DIR.joinpath(".build-repo")
|
||||||
@ -21,56 +44,6 @@ SOURCE_REPO = BASE_DIR.joinpath(".source-repo")
|
|||||||
DEPLOY_REPO = BASE_DIR.joinpath(".deploy-repo")
|
DEPLOY_REPO = BASE_DIR.joinpath(".deploy-repo")
|
||||||
WK_DIR = BASE_DIR.joinpath(".tmp")
|
WK_DIR = BASE_DIR.joinpath(".tmp")
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
group = parser.add_mutually_exclusive_group()
|
|
||||||
group.add_argument(
|
|
||||||
"--nodeploy",
|
|
||||||
required=False,
|
|
||||||
action="store_true",
|
|
||||||
help="Do not deploy repo to web server root",
|
|
||||||
)
|
|
||||||
group.add_argument(
|
|
||||||
"--onlydeploy",
|
|
||||||
required=False,
|
|
||||||
action="store_true",
|
|
||||||
help="Skip the build steps and only deploy repo to web server root",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--sourceurl",
|
|
||||||
required=False,
|
|
||||||
action="store",
|
|
||||||
default="https://pagure.io/workstation-ostree-config",
|
|
||||||
help="URL for source repo",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--sourcebranch",
|
|
||||||
required=True,
|
|
||||||
action="store",
|
|
||||||
help="Branch of source repo",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--treefile",
|
|
||||||
required=False,
|
|
||||||
action="store",
|
|
||||||
default="vauxite.yaml",
|
|
||||||
help="Treefile to use for rpm-ostree",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--ostreebranch",
|
|
||||||
required=True,
|
|
||||||
action="store",
|
|
||||||
help="Name of ref branch",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--destrepo",
|
|
||||||
required=False,
|
|
||||||
action="store",
|
|
||||||
default="/srv/repo",
|
|
||||||
help="Destination for rsync-repos",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def print_log(msg: str):
|
def print_log(msg: str):
|
||||||
if sys.stdout.isatty():
|
if sys.stdout.isatty():
|
||||||
@ -82,9 +55,9 @@ def print_log(msg: str):
|
|||||||
|
|
||||||
def handle_err():
|
def handle_err():
|
||||||
print_log("ERROR:")
|
print_log("ERROR:")
|
||||||
print("{}" % sys.exc_info()[0])
|
print(f"{sys.exc_info()[0]}")
|
||||||
print("{}" % sys.exc_info()[1])
|
print(f"{sys.exc_info()[1]}")
|
||||||
print("{}" % sys.exc_info()[2])
|
print(f"{sys.exc_info()[2]}")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -92,7 +65,8 @@ def clean_wk_dir():
|
|||||||
try:
|
try:
|
||||||
print_log("Clean working directory")
|
print_log("Clean working directory")
|
||||||
shutil.rmtree(CACHE_DIR)
|
shutil.rmtree(CACHE_DIR)
|
||||||
shutil.rmtree(SOURCE_REPO)
|
if not args.get("--no-download-sources"):
|
||||||
|
shutil.rmtree(SOURCE_REPO)
|
||||||
shutil.rmtree(WK_DIR)
|
shutil.rmtree(WK_DIR)
|
||||||
for dir in glob("/tmp/rpmostree*", recursive=True):
|
for dir in glob("/tmp/rpmostree*", recursive=True):
|
||||||
shutil.rmtree(dir)
|
shutil.rmtree(dir)
|
||||||
@ -113,7 +87,8 @@ def run_proc(cmd: str, capture_output=False) -> subprocess.CompletedProcess:
|
|||||||
|
|
||||||
|
|
||||||
def prepare_build_env():
|
def prepare_build_env():
|
||||||
clean_wk_dir()
|
if not args.get("--no-clean"):
|
||||||
|
clean_wk_dir()
|
||||||
|
|
||||||
print_log("Ensure CACHE_DIR exists")
|
print_log("Ensure CACHE_DIR exists")
|
||||||
CACHE_DIR.mkdir(exist_ok=True)
|
CACHE_DIR.mkdir(exist_ok=True)
|
||||||
@ -133,14 +108,14 @@ def prepare_build_env():
|
|||||||
else:
|
else:
|
||||||
print_log("Pull existing deploy repo into local build repo")
|
print_log("Pull existing deploy repo into local build repo")
|
||||||
run_proc(
|
run_proc(
|
||||||
f"ostree --repo={BUILD_REPO} pull-local --depth=2 {DEPLOY_REPO} {args.ostreebranch}"
|
f"ostree --repo={BUILD_REPO} pull-local --depth=2 {DEPLOY_REPO} {args.get("--ostree-branch")}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not SOURCE_REPO.exists():
|
if not SOURCE_REPO.exists():
|
||||||
print_log(
|
print_log(
|
||||||
f"Clone branch {args.sourcebranch} of {args.sourceurl} into SOURCE_REPO"
|
f"Clone branch {args.get("--source-branch")} of {args.get("--source-url")} into SOURCE_REPO"
|
||||||
)
|
)
|
||||||
run_proc(f"git clone -b {args.sourcebranch} {args.sourceurl} {SOURCE_REPO}")
|
run_proc(f"git clone -b {args.get("--source-branch")} {args.get("--source-url")} {SOURCE_REPO}")
|
||||||
|
|
||||||
print_log("Copy SOURCE_REPO contents into WK_DIR")
|
print_log("Copy SOURCE_REPO contents into WK_DIR")
|
||||||
run_proc(f"rsync -aAX {SOURCE_REPO}/ {WK_DIR}")
|
run_proc(f"rsync -aAX {SOURCE_REPO}/ {WK_DIR}")
|
||||||
@ -165,12 +140,30 @@ def compose_ostree():
|
|||||||
f"--cachedir={CACHE_DIR}",
|
f"--cachedir={CACHE_DIR}",
|
||||||
f"--repo={BUILD_REPO}",
|
f"--repo={BUILD_REPO}",
|
||||||
f"--add-metadata-string=Build={time_fmt}",
|
f"--add-metadata-string=Build={time_fmt}",
|
||||||
WK_DIR.joinpath(args.treefile),
|
WK_DIR.joinpath(args.get("--treefile")),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sign_commit():
|
||||||
|
commit_id = subprocess.run(["ostree", f"--repo={DEPLOY_REPO}", "rev-parse", args.get("--ostree-branch")], capture_output=True, text=True)
|
||||||
|
|
||||||
|
with open(args.get("--gpg-passfile"), "r") as json_file:
|
||||||
|
gpg_data = json.loads(json_file.read())
|
||||||
|
|
||||||
|
print_log(f"Signing rpm-ostree commit {commit_id.stdout} with GPG key-id {gpg_data.get("gpg-id")}")
|
||||||
|
|
||||||
|
gpg_cmd = f"echo {gpg_data.get("passphrase")} | gpg --batch --always-trust --yes --passphrase-fd 0 --pinentry-mode=loopback -s $(mktemp)"
|
||||||
|
run_gpg_cmd = subprocess.Popen(gpg_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
output = run_gpg_cmd.communicate()[0]
|
||||||
|
if output:
|
||||||
|
print_log(f"Error unlocking GPG keyring: {output}")
|
||||||
|
exit(99)
|
||||||
|
|
||||||
|
run_proc(f"ostree --repo={DEPLOY_REPO} gpg-sign {commit_id.stdout} {gpg_data.get("gpg-id")}")
|
||||||
|
|
||||||
|
|
||||||
def prepare_deploy():
|
def prepare_deploy():
|
||||||
print_log("Prune refs older than 30 days")
|
print_log("Prune refs older than 30 days")
|
||||||
run_proc(
|
run_proc(
|
||||||
@ -179,38 +172,38 @@ def prepare_deploy():
|
|||||||
|
|
||||||
print_log("Pull new ostree commit into DEPLOY_REPO")
|
print_log("Pull new ostree commit into DEPLOY_REPO")
|
||||||
run_proc(
|
run_proc(
|
||||||
f"ostree --repo={DEPLOY_REPO} pull-local --depth=1 {BUILD_REPO} {args.ostreebranch}"
|
f"ostree --repo={DEPLOY_REPO} pull-local --depth=1 {BUILD_REPO} {args.get("--ostree-branch")}"
|
||||||
)
|
)
|
||||||
|
|
||||||
print_log("Remove local build repo")
|
print_log("Remove local build repo")
|
||||||
shutil.rmtree(BUILD_REPO, ignore_errors=True)
|
shutil.rmtree(BUILD_REPO, ignore_errors=True)
|
||||||
|
|
||||||
print_log("Check filesystem for errors")
|
print_log("Check filesystem for errors")
|
||||||
run_proc(f"ostree --repo={DEPLOY_REPO} fsck {args.ostreebranch}")
|
run_proc(f"ostree --repo={DEPLOY_REPO} fsck {args.get("--ostree-branch")}")
|
||||||
|
|
||||||
|
|
||||||
def generate_deltas():
|
def generate_deltas():
|
||||||
print_log("Check if main ref has parent")
|
print_log("Check if main ref has parent")
|
||||||
check_parent = run_proc(
|
check_parent = run_proc(
|
||||||
f"ostree --repo={DEPLOY_REPO} show {args.ostreebranch}", capture_output=True
|
f"ostree --repo={DEPLOY_REPO} show {args.get("--ostree-branch")}", capture_output=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if not check_parent.stderr:
|
if not check_parent.stderr:
|
||||||
print_log("Generate static delta from main ref's parent")
|
print_log("Generate static delta from main ref's parent")
|
||||||
run_proc(
|
run_proc(
|
||||||
f"ostree --repo={DEPLOY_REPO} static-delta generate {args.ostreebranch}"
|
f"ostree --repo={DEPLOY_REPO} static-delta generate {args.get("--ostree-branch")}"
|
||||||
)
|
)
|
||||||
|
|
||||||
print_log("Check if main ref's parent has parent")
|
print_log("Check if main ref's parent has parent")
|
||||||
check_gparent = run_proc(
|
check_gparent = run_proc(
|
||||||
f"ostree --repo={DEPLOY_REPO} show {args.ostreebranch}^^",
|
f"ostree --repo={DEPLOY_REPO} show {args.get("--ostree-branch")}^^",
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not check_gparent.stderr:
|
if not check_gparent.stderr:
|
||||||
print_log("Generate static delta from parent of main ref's parent")
|
print_log("Generate static delta from parent of main ref's parent")
|
||||||
run_proc(
|
run_proc(
|
||||||
f"ostree --repo={DEPLOY_REPO} static-delta generate --from={args.ostreebranch}^^ --to={args.ostreebranch}"
|
f"ostree --repo={DEPLOY_REPO} static-delta generate --from={args.get("--ostree-branch")}^^ --to={args.get("--ostree-branch")}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print_log("Main ref's parent has no parent. No deltas generated.")
|
print_log("Main ref's parent has no parent. No deltas generated.")
|
||||||
@ -226,24 +219,19 @@ def update_summary():
|
|||||||
def deploy_repo():
|
def deploy_repo():
|
||||||
print_log("Deploying repo to web server root")
|
print_log("Deploying repo to web server root")
|
||||||
if DEPLOY_REPO.exists():
|
if DEPLOY_REPO.exists():
|
||||||
run_proc(f"{BASE_DIR}/rsync-repos --src {DEPLOY_REPO} --dest {args.destrepo}")
|
run_proc(f"{BASE_DIR}/rsync-repos --src {DEPLOY_REPO} --dest {args.get("--dest-repo")}")
|
||||||
else:
|
else:
|
||||||
print_log("DEPLOY_REPO not found. Not deploying to web server")
|
print_log("DEPLOY_REPO not found. Not deploying to web server")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if args.nodeploy:
|
args = docopt(__doc__, help=True, version="ostree-engine 0.1.0")
|
||||||
prepare_build_env()
|
prepare_build_env()
|
||||||
compose_ostree()
|
compose_ostree()
|
||||||
prepare_deploy()
|
prepare_deploy()
|
||||||
generate_deltas()
|
generate_deltas()
|
||||||
update_summary()
|
if args.get("--gpg-passfile"):
|
||||||
elif args.onlydeploy:
|
sign_commit()
|
||||||
deploy_repo()
|
update_summary()
|
||||||
else:
|
if not args.get("--no-deploy"):
|
||||||
prepare_build_env()
|
|
||||||
compose_ostree()
|
|
||||||
prepare_deploy()
|
|
||||||
generate_deltas()
|
|
||||||
update_summary()
|
|
||||||
deploy_repo()
|
deploy_repo()
|
||||||
|
24
src/borgmatic-config.yaml
Normal file
24
src/borgmatic-config.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
source_directories:
|
||||||
|
- /var/home
|
||||||
|
- /etc
|
||||||
|
- /usr/local
|
||||||
|
repositories:
|
||||||
|
- path: /srv/backup/localhost
|
||||||
|
label: localhost-backup
|
||||||
|
exclude_caches: true
|
||||||
|
compression: zstd
|
||||||
|
relocated_repo_access_is_ok: true
|
||||||
|
unknown_unencrypted_repo_access_is_ok: true
|
||||||
|
keep_daily: 7
|
||||||
|
keep_weekly: 4
|
||||||
|
keep_monthly: 6
|
||||||
|
keep_yearly: 1
|
||||||
|
checks:
|
||||||
|
- name: repository
|
||||||
|
frequency: 2 weeks
|
||||||
|
- name: archives
|
||||||
|
frequency: 2 weeks
|
||||||
|
check_repositories:
|
||||||
|
- /srv/backup/localhost
|
||||||
|
check_last: 3
|
||||||
|
encryption_passcommand: secret-tool lookup borg-repo localhost
|
12
src/user-dirs.defaults
Normal file
12
src/user-dirs.defaults
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Default settings for user directories
|
||||||
|
#
|
||||||
|
# The values are relative pathnames from the home directory and
|
||||||
|
# will be translated on a per-path-element basis into the users locale
|
||||||
|
DESKTOP=desktop
|
||||||
|
DOWNLOAD=downloads
|
||||||
|
TEMPLATES=
|
||||||
|
PUBLICSHARE=sync
|
||||||
|
DOCUMENTS=sync/documents
|
||||||
|
MUSIC=
|
||||||
|
PICTURES=sync/pictures
|
||||||
|
VIDEOS=
|
@ -1,10 +0,0 @@
|
|||||||
[copr:copr.fedorainfracloud.org:varlad:zellij]
|
|
||||||
name=Copr repo for zellij owned by varlad
|
|
||||||
baseurl=https://download.copr.fedorainfracloud.org/results/varlad/zellij/fedora-39-x86_64/
|
|
||||||
type=rpm-md
|
|
||||||
skip_if_unavailable=True
|
|
||||||
gpgcheck=1
|
|
||||||
gpgkey=https://download.copr.fedorainfracloud.org/results/varlad/zellij/pubkey.gpg
|
|
||||||
repo_gpgcheck=0
|
|
||||||
enabled=1
|
|
||||||
enabled_metadata=1
|
|
40
src/vauxite.json
Normal file
40
src/vauxite.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"ref": "vauxite/f39/x86_64/main",
|
||||||
|
"include": "xfce-desktop-pkgs.yaml",
|
||||||
|
"packages": [
|
||||||
|
"borgbackup",
|
||||||
|
"borgmatic",
|
||||||
|
"cronie",
|
||||||
|
"distrobox",
|
||||||
|
"fedora-release-ostree-desktop",
|
||||||
|
"fontconfig-enhanced-defaults",
|
||||||
|
"fontconfig-font-replacements",
|
||||||
|
"rofi",
|
||||||
|
"snapper",
|
||||||
|
"vim-default-editor",
|
||||||
|
"xfce4-cpugraph-plugin",
|
||||||
|
"xfce4-genmon-plugin",
|
||||||
|
"xfce4-weather-plugin"
|
||||||
|
],
|
||||||
|
"repos": [
|
||||||
|
"fedora",
|
||||||
|
"updates",
|
||||||
|
"copr:copr.fedorainfracloud.org:hyperreal:better_fonts"
|
||||||
|
],
|
||||||
|
"add-files": [
|
||||||
|
[
|
||||||
|
"borgmatic-config.yaml",
|
||||||
|
"/etc/borgmatic/config.yaml"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"user-dirs.defaults",
|
||||||
|
"/etc/xdg/user-dirs.defaults"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"units": [
|
||||||
|
"snapper-cleanup.timer",
|
||||||
|
"snapper-timeline.timer"
|
||||||
|
],
|
||||||
|
"cliwrap": true,
|
||||||
|
"readonly-executables": true
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
ref: vauxite/f39/x86_64/main
|
|
||||||
|
|
||||||
include: xfce-desktop-pkgs.yaml
|
|
||||||
|
|
||||||
rojig:
|
|
||||||
name: vauxite
|
|
||||||
summary: "Vauxite base image"
|
|
||||||
license: MIT
|
|
||||||
description: "OSTree-based Fedora Xfce Desktop"
|
|
||||||
|
|
||||||
packages:
|
|
||||||
- distrobox
|
|
||||||
- fedora-release-ostree-desktop
|
|
||||||
- rofi
|
|
||||||
- snapper
|
|
||||||
- vim-default-editor
|
|
||||||
- xfce4-cpugraph-plugin
|
|
||||||
- xfce4-genmon-plugin
|
|
||||||
- xfce4-weather-plugin
|
|
||||||
|
|
||||||
repo-packages:
|
|
||||||
- packages:
|
|
||||||
- fontconfig-enhanced-defaults
|
|
||||||
- fontconfig-font-replacements
|
|
||||||
repo: copr:copr.fedorainfracloud.org:hyperreal:better_fonts
|
|
||||||
- packages:
|
|
||||||
- zellij
|
|
||||||
repo: copr:copr.fedorainfracloud.org:varlad:zellij
|
|
||||||
|
|
||||||
repos:
|
|
||||||
- fedora
|
|
||||||
- updates
|
|
||||||
- copr:copr.fedorainfracloud.org:hyperreal:better_fonts
|
|
||||||
- copr:copr.fedorainfracloud.org:varlad:zellij
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user