mirror of
https://codeberg.org/hyperreal/vauxite-build
synced 2024-11-01 16:53:12 +01:00
Refactor; add sign_commit()
This commit is contained in:
parent
d3066bf6a5
commit
ca05f01dd6
138
ostree-engine
138
ostree-engine
@ -1,19 +1,42 @@
|
||||
#!/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 json
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from docopt import docopt
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
|
||||
if os.geteuid() != 0:
|
||||
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")
|
||||
CACHE_DIR = BASE_DIR.joinpath(".cache")
|
||||
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")
|
||||
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):
|
||||
if sys.stdout.isatty():
|
||||
@ -82,9 +55,9 @@ def print_log(msg: str):
|
||||
|
||||
def handle_err():
|
||||
print_log("ERROR:")
|
||||
print("{}" % sys.exc_info()[0])
|
||||
print("{}" % sys.exc_info()[1])
|
||||
print("{}" % sys.exc_info()[2])
|
||||
print(f"{sys.exc_info()[0]}")
|
||||
print(f"{sys.exc_info()[1]}")
|
||||
print(f"{sys.exc_info()[2]}")
|
||||
exit(1)
|
||||
|
||||
|
||||
@ -92,6 +65,7 @@ def clean_wk_dir():
|
||||
try:
|
||||
print_log("Clean working directory")
|
||||
shutil.rmtree(CACHE_DIR)
|
||||
if not args.get("--no-download-sources"):
|
||||
shutil.rmtree(SOURCE_REPO)
|
||||
shutil.rmtree(WK_DIR)
|
||||
for dir in glob("/tmp/rpmostree*", recursive=True):
|
||||
@ -113,6 +87,7 @@ def run_proc(cmd: str, capture_output=False) -> subprocess.CompletedProcess:
|
||||
|
||||
|
||||
def prepare_build_env():
|
||||
if not args.get("--no-clean"):
|
||||
clean_wk_dir()
|
||||
|
||||
print_log("Ensure CACHE_DIR exists")
|
||||
@ -133,14 +108,14 @@ def prepare_build_env():
|
||||
else:
|
||||
print_log("Pull existing deploy repo into local build repo")
|
||||
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():
|
||||
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")
|
||||
run_proc(f"rsync -aAX {SOURCE_REPO}/ {WK_DIR}")
|
||||
@ -165,12 +140,30 @@ def compose_ostree():
|
||||
f"--cachedir={CACHE_DIR}",
|
||||
f"--repo={BUILD_REPO}",
|
||||
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():
|
||||
print_log("Prune refs older than 30 days")
|
||||
run_proc(
|
||||
@ -179,38 +172,38 @@ def prepare_deploy():
|
||||
|
||||
print_log("Pull new ostree commit into DEPLOY_REPO")
|
||||
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")
|
||||
shutil.rmtree(BUILD_REPO, ignore_errors=True)
|
||||
|
||||
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():
|
||||
print_log("Check if main ref has parent")
|
||||
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:
|
||||
print_log("Generate static delta from main ref's parent")
|
||||
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")
|
||||
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,
|
||||
)
|
||||
|
||||
if not check_gparent.stderr:
|
||||
print_log("Generate static delta from parent of main ref's parent")
|
||||
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:
|
||||
print_log("Main ref's parent has no parent. No deltas generated.")
|
||||
@ -226,24 +219,19 @@ def update_summary():
|
||||
def deploy_repo():
|
||||
print_log("Deploying repo to web server root")
|
||||
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:
|
||||
print_log("DEPLOY_REPO not found. Not deploying to web server")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if args.nodeploy:
|
||||
prepare_build_env()
|
||||
compose_ostree()
|
||||
prepare_deploy()
|
||||
generate_deltas()
|
||||
update_summary()
|
||||
elif args.onlydeploy:
|
||||
deploy_repo()
|
||||
else:
|
||||
args = docopt(__doc__, help=True, version="ostree-engine 0.1.0")
|
||||
prepare_build_env()
|
||||
compose_ostree()
|
||||
prepare_deploy()
|
||||
generate_deltas()
|
||||
if args.get("--gpg-passfile"):
|
||||
sign_commit()
|
||||
update_summary()
|
||||
if not args.get("--no-deploy"):
|
||||
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