Extract download utils
This commit is contained in:
parent
a08149daea
commit
a0c0599e7b
|
@ -111,10 +111,6 @@ systemd_nspawn_default_args=--bind-ro=/sys/module
|
|||
# Always add --bind-ro=/sys/module to make lsmod happy
|
||||
# https://manpages.debian.org/bookworm/manpages/sysfs.5.en.html
|
||||
|
||||
DOWNLOAD_SCRIPT_DIGEST = (
|
||||
"cfcb5d08b24187d108f2ab0d21a6cc4b73dcd7f5d7dfc80803bfd7f1642d638d"
|
||||
)
|
||||
|
||||
from utils.paths import SCRIPT_PATH, SCRIPT_NAME, SCRIPT_DIR_PATH
|
||||
from utils.paths import JAILS_DIR_PATH, JAIL_CONFIG_NAME, JAIL_ROOTFS_NAME
|
||||
from utils.paths import COMMAND_NAME, SHORTNAME
|
||||
|
@ -175,95 +171,6 @@ def cleanup(jail_path):
|
|||
shutil.rmtree(jail_path, onerror=_onerror)
|
||||
|
||||
|
||||
def validate_sha256(file_path, digest):
|
||||
"""
|
||||
Validates if a file matches a sha256 digest.
|
||||
"""
|
||||
try:
|
||||
with open(file_path, "rb") as f:
|
||||
file_hash = hashlib.sha256(f.read()).hexdigest()
|
||||
return file_hash == digest
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
|
||||
|
||||
def run_lxc_download_script(
|
||||
jail_name=None, jail_path=None, jail_rootfs_path=None, distro=None, release=None
|
||||
):
|
||||
arch = "amd64"
|
||||
lxc_dir = ".lxc"
|
||||
lxc_cache = os.path.join(lxc_dir, "cache")
|
||||
lxc_download_script = os.path.join(lxc_dir, "lxc-download.sh")
|
||||
|
||||
# Create the lxc dirs if nonexistent
|
||||
os.makedirs(lxc_dir, exist_ok=True)
|
||||
stat_chmod(lxc_dir, 0o700)
|
||||
os.makedirs(lxc_cache, exist_ok=True)
|
||||
stat_chmod(lxc_cache, 0o700)
|
||||
|
||||
try:
|
||||
if os.stat(lxc_download_script).st_uid != 0:
|
||||
os.remove(lxc_download_script)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Fetch the lxc download script if not present locally (or hash doesn't match)
|
||||
if not validate_sha256(lxc_download_script, DOWNLOAD_SCRIPT_DIGEST):
|
||||
urllib.request.urlretrieve(
|
||||
"https://raw.githubusercontent.com/Jip-Hop/lxc/97f93be72ebf380f3966259410b70b1c966b0ff0/templates/lxc-download.in",
|
||||
lxc_download_script,
|
||||
)
|
||||
|
||||
if not validate_sha256(lxc_download_script, DOWNLOAD_SCRIPT_DIGEST):
|
||||
eprint("Abort! Downloaded script has unexpected contents.")
|
||||
return 1
|
||||
|
||||
stat_chmod(lxc_download_script, 0o700)
|
||||
|
||||
if None not in [jail_name, jail_path, jail_rootfs_path, distro, release]:
|
||||
cmd = [
|
||||
lxc_download_script,
|
||||
f"--name={jail_name}",
|
||||
f"--path={jail_path}",
|
||||
f"--rootfs={jail_rootfs_path}",
|
||||
f"--arch={arch}",
|
||||
f"--dist={distro}",
|
||||
f"--release={release}",
|
||||
]
|
||||
|
||||
if rc := subprocess.run(cmd, env={"LXC_CACHE_PATH": lxc_cache}).returncode != 0:
|
||||
eprint("Aborting...")
|
||||
return rc
|
||||
|
||||
else:
|
||||
# List images
|
||||
cmd = [lxc_download_script, "--list", f"--arch={arch}"]
|
||||
|
||||
p1 = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE, env={"LXC_CACHE_PATH": lxc_cache}
|
||||
)
|
||||
|
||||
for line in iter(p1.stdout.readline, b""):
|
||||
line = line.decode().strip()
|
||||
# Filter out the known incompatible distros
|
||||
if not re.match(
|
||||
r"^(alpine|amazonlinux|busybox|devuan|funtoo|openwrt|plamo|voidlinux)\s",
|
||||
line,
|
||||
):
|
||||
# TODO: check if output matches expected output, if it does then return 0
|
||||
# Else treat this as an error and return 1
|
||||
print(line)
|
||||
|
||||
rc = p1.wait()
|
||||
# Currently --list will always return a non-zero exit code, even when listing the images was successful
|
||||
# https://github.com/lxc/lxc/pull/4462
|
||||
# Therefore we must currently return 0, to prevent aborting the interactive create process
|
||||
|
||||
# return rc
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
from utils.files import stat_chmod
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
# SPDX-FileCopyrightText: © 2024 Jip-Hop and the Jailmakers <https://github.com/Jip-Hop/jailmaker>
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from utils.files import stat_chmod
|
||||
|
||||
|
||||
DOWNLOAD_SCRIPT_DIGEST = (
|
||||
"cfcb5d08b24187d108f2ab0d21a6cc4b73dcd7f5d7dfc80803bfd7f1642d638d"
|
||||
)
|
||||
|
||||
|
||||
def run_lxc_download_script(
|
||||
jail_name=None, jail_path=None, jail_rootfs_path=None, distro=None, release=None
|
||||
):
|
||||
arch = "amd64"
|
||||
lxc_dir = ".lxc"
|
||||
lxc_cache = os.path.join(lxc_dir, "cache")
|
||||
lxc_download_script = os.path.join(lxc_dir, "lxc-download.sh")
|
||||
|
||||
# Create the lxc dirs if nonexistent
|
||||
os.makedirs(lxc_dir, exist_ok=True)
|
||||
stat_chmod(lxc_dir, 0o700)
|
||||
os.makedirs(lxc_cache, exist_ok=True)
|
||||
stat_chmod(lxc_cache, 0o700)
|
||||
|
||||
try:
|
||||
if os.stat(lxc_download_script).st_uid != 0:
|
||||
os.remove(lxc_download_script)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Fetch the lxc download script if not present locally (or hash doesn't match)
|
||||
if not validate_sha256(lxc_download_script, DOWNLOAD_SCRIPT_DIGEST):
|
||||
urllib.request.urlretrieve(
|
||||
"https://raw.githubusercontent.com/Jip-Hop/lxc/97f93be72ebf380f3966259410b70b1c966b0ff0/templates/lxc-download.in",
|
||||
lxc_download_script,
|
||||
)
|
||||
|
||||
if not validate_sha256(lxc_download_script, DOWNLOAD_SCRIPT_DIGEST):
|
||||
eprint("Abort! Downloaded script has unexpected contents.")
|
||||
return 1
|
||||
|
||||
stat_chmod(lxc_download_script, 0o700)
|
||||
|
||||
if None not in [jail_name, jail_path, jail_rootfs_path, distro, release]:
|
||||
cmd = [
|
||||
lxc_download_script,
|
||||
f"--name={jail_name}",
|
||||
f"--path={jail_path}",
|
||||
f"--rootfs={jail_rootfs_path}",
|
||||
f"--arch={arch}",
|
||||
f"--dist={distro}",
|
||||
f"--release={release}",
|
||||
]
|
||||
|
||||
if rc := subprocess.run(cmd, env={"LXC_CACHE_PATH": lxc_cache}).returncode != 0:
|
||||
eprint("Aborting...")
|
||||
return rc
|
||||
|
||||
else:
|
||||
# List images
|
||||
cmd = [lxc_download_script, "--list", f"--arch={arch}"]
|
||||
|
||||
p1 = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE, env={"LXC_CACHE_PATH": lxc_cache}
|
||||
)
|
||||
|
||||
for line in iter(p1.stdout.readline, b""):
|
||||
line = line.decode().strip()
|
||||
# Filter out the known incompatible distros
|
||||
if not re.match(
|
||||
r"^(alpine|amazonlinux|busybox|devuan|funtoo|openwrt|plamo|voidlinux)\s",
|
||||
line,
|
||||
):
|
||||
# TODO: check if output matches expected output, if it does then return 0
|
||||
# Else treat this as an error and return 1
|
||||
print(line)
|
||||
|
||||
rc = p1.wait()
|
||||
# Currently --list will always return a non-zero exit code, even when listing the images was successful
|
||||
# https://github.com/lxc/lxc/pull/4462
|
||||
# Therefore we must currently return 0, to prevent aborting the interactive create process
|
||||
|
||||
# return rc
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def validate_sha256(file_path, digest):
|
||||
"""
|
||||
Validates if a file matches a sha256 digest.
|
||||
"""
|
||||
try:
|
||||
with open(file_path, "rb") as f:
|
||||
file_hash = hashlib.sha256(f.read()).hexdigest()
|
||||
return file_hash == digest
|
||||
except FileNotFoundError:
|
||||
return False
|
Loading…
Reference in New Issue