Skip to content

Commit 89bb9c0

Browse files
committed
Refactor code
Make it easy to change temp dir in the future. Release zypper lock and delete temp dir in less ideal cases of exit
1 parent f371b1c commit 89bb9c0

File tree

1 file changed

+65
-49
lines changed

1 file changed

+65
-49
lines changed

zypperoni

Lines changed: 65 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ from shlex import quote
2727
import xml.etree.ElementTree as ET
2828

2929
# Constants
30-
ZYPPERONI_VERSION = "0.2.3"
30+
ZYPPERONI_VERSION = "0.3.0"
31+
ZYPPERONI_TMP_DIR = "/tmp/zypperoni"
3132
ZYPPER_PID_FILE = "/run/zypp.pid"
3233
VALID_CMD = ["ref", "force-ref", "in", "in-download", "dup", "dup-download", "inr", "inr-download"]
3334
VALID_OPT = ["--debug", "--help", "--version", "--no-confirm", "--max-jobs"]
@@ -60,64 +61,64 @@ Options:
6061
"""
6162

6263
# Shell commands to prepare temp mounts for zypper refresh
63-
refresh_mount_commands = """
64-
mkdir -p /tmp/zypperoni/{uuid}/rootfs;
65-
mkdir -p /tmp/zypperoni/{uuid}/run;
66-
mkdir -p /tmp/zypperoni/{uuid}/var/cache/zypp;
67-
mkdir -p /tmp/zypperoni/{uuid}/var/lib/ca-certificates;
64+
refresh_mount_commands = f"""
65+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs;
66+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/run;
67+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/var/cache/zypp;
68+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/var/lib/ca-certificates;
6869
if readlink /etc/resolv.conf; then
6970
RESOLV_PATH=$(readlink /etc/resolv.conf);
70-
TEMP_DIR=/tmp/zypperoni/{uuid}"$(dirname "$RESOLV_PATH")";
71+
TEMP_DIR={ZYPPERONI_TMP_DIR}/{{uuid}}"$(dirname "$RESOLV_PATH")";
7172
mkdir -p "$TEMP_DIR";
7273
cat "$RESOLV_PATH" > "$TEMP_DIR"/"$(basename "$RESOLV_PATH")";
7374
fi;
74-
mount -o bind,ro / /tmp/zypperoni/{uuid}/rootfs;
75-
mount -t devtmpfs none /tmp/zypperoni/{uuid}/rootfs/dev;
76-
mount -t tmpfs none /tmp/zypperoni/{uuid}/rootfs/tmp;
77-
mount -o bind /tmp/zypperoni/{uuid}/run /tmp/zypperoni/{uuid}/rootfs/run;
78-
mount -o bind /tmp/zypperoni/{uuid}/var /tmp/zypperoni/{uuid}/rootfs/var;
79-
mount -o bind /var/cache/zypp /tmp/zypperoni/{uuid}/rootfs/var/cache/zypp;
80-
mount -o bind,ro /var/lib/ca-certificates /tmp/zypperoni/{uuid}/rootfs/var/lib/ca-certificates;
75+
mount -o bind,ro / {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs;
76+
mount -t devtmpfs none {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/dev;
77+
mount -t tmpfs none {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/tmp;
78+
mount -o bind {ZYPPERONI_TMP_DIR}/{{uuid}}/run {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/run;
79+
mount -o bind {ZYPPERONI_TMP_DIR}/{{uuid}}/var {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var;
80+
mount -o bind /var/cache/zypp {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var/cache/zypp;
81+
mount -o bind,ro /var/lib/ca-certificates {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var/lib/ca-certificates;
8182
"""
8283

8384
# Shell commands to perform zypper refresh / force-refresh
84-
refresh_shell_commands = """
85-
chroot /tmp/zypperoni/{uuid}/rootfs env -i zypper --non-interactive {refresh_type} {repo_alias};
85+
refresh_shell_commands = f"""
86+
chroot {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs env -i zypper --non-interactive {{refresh_type}} {{repo_alias}};
8687
"""
8788

8889
# Shell commands to prepare temp mounts for zypper download
89-
download_mount_commands = """
90-
mkdir -p /tmp/zypperoni/{uuid}/rootfs;
91-
mkdir -p /tmp/zypperoni/{uuid}/run;
92-
mkdir -p /tmp/zypperoni/{uuid}/var/cache/zypp;
93-
mkdir -p /tmp/zypperoni/{uuid}/var/lib/ca-certificates;
90+
download_mount_commands = f"""
91+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs;
92+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/run;
93+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/var/cache/zypp;
94+
mkdir -p {ZYPPERONI_TMP_DIR}/{{uuid}}/var/lib/ca-certificates;
9495
if readlink /etc/resolv.conf; then
9596
RESOLV_PATH=$(readlink /etc/resolv.conf);
96-
TEMP_DIR=/tmp/zypperoni/{uuid}"$(dirname "$RESOLV_PATH")";
97+
TEMP_DIR={ZYPPERONI_TMP_DIR}/{{uuid}}"$(dirname "$RESOLV_PATH")";
9798
mkdir -p "$TEMP_DIR";
9899
cat "$RESOLV_PATH" > "$TEMP_DIR"/"$(basename "$RESOLV_PATH")";
99100
fi;
100-
mount -o bind,ro / /tmp/zypperoni/{uuid}/rootfs;
101-
mount -o bind /tmp/zypperoni/{uuid}/run /tmp/zypperoni/{uuid}/rootfs/run;
102-
mount -o bind /tmp/zypperoni/{uuid}/var /tmp/zypperoni/{uuid}/rootfs/var;
103-
mount -o bind /var/cache/zypp /tmp/zypperoni/{uuid}/rootfs/var/cache/zypp;
104-
mount -o bind,ro /var/lib/ca-certificates /tmp/zypperoni/{uuid}/rootfs/var/lib/ca-certificates;
101+
mount -o bind,ro / {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs;
102+
mount -o bind {ZYPPERONI_TMP_DIR}/{{uuid}}/run {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/run;
103+
mount -o bind {ZYPPERONI_TMP_DIR}/{{uuid}}/var {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var;
104+
mount -o bind /var/cache/zypp {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var/cache/zypp;
105+
mount -o bind,ro /var/lib/ca-certificates {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var/lib/ca-certificates;
105106
"""
106107

107108
# Shell commands to perform zypper download
108-
download_shell_commands = """
109-
chroot /tmp/zypperoni/{uuid}/rootfs env -i zypper --non-interactive download {pkg_name};
109+
download_shell_commands = f"""
110+
chroot {ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs env -i zypper --non-interactive download {{pkg_name}};
110111
"""
111112

112113
# Dirs to unmount (one per line)
113-
umount_dirs = """
114-
/tmp/zypperoni/{uuid}/rootfs/var/lib/ca-certificates
115-
/tmp/zypperoni/{uuid}/rootfs/var/cache/zypp
116-
/tmp/zypperoni/{uuid}/rootfs/var
117-
/tmp/zypperoni/{uuid}/rootfs/run
118-
/tmp/zypperoni/{uuid}/rootfs/tmp
119-
/tmp/zypperoni/{uuid}/rootfs/dev
120-
/tmp/zypperoni/{uuid}/rootfs
114+
umount_dirs = f"""
115+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var/lib/ca-certificates
116+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var/cache/zypp
117+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/var
118+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/run
119+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/tmp
120+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs/dev
121+
{ZYPPERONI_TMP_DIR}/{{uuid}}/rootfs
121122
"""
122123

123124
################################
@@ -161,7 +162,7 @@ def unmount(UUID):
161162
umount_counter = 0
162163
for uuid in UUID:
163164
UMNT_OK = True
164-
if os.path.isdir(f"/tmp/zypperoni/{uuid}/rootfs"):
165+
if os.path.isdir(f"{ZYPPERONI_TMP_DIR}/{uuid}/rootfs"):
165166
dirs = umount_dirs.format(uuid=uuid)
166167
dirs = dirs.strip().split("\n")
167168
for dir in dirs:
@@ -177,7 +178,7 @@ def unmount(UUID):
177178
# Function to recursively delete temp files
178179
def recursive_delete(path):
179180
# perform some sanity checks
180-
if not path.startswith("/tmp/zypperoni"):
181+
if not path.startswith(ZYPPERONI_TMP_DIR):
181182
return False
182183
command = f"rm -r {quote(path)} > /dev/null 2>&1"
183184
os.system(command)
@@ -196,7 +197,7 @@ async def zypper_task(lock, UUID, task_type, task_item, total_items, item_counte
196197
uuid = UUID.pop()
197198
log_messages = {}
198199
commands = ""
199-
temp_dir = f"/tmp/zypperoni/{uuid}/rootfs"
200+
temp_dir = f"{ZYPPERONI_TMP_DIR}/{uuid}/rootfs"
200201
if task_type == "ref":
201202
log_messages.update({"start": f"Refreshing repo [{item_counter}/{total_items}] {task_item!r}"})
202203
log_messages.update({"success": f"Successfully refreshed repo {task_item!r}"})
@@ -316,7 +317,7 @@ async def main_task(num_jobs, task_type, task_items, no_confirm=None):
316317
unmount(UUID_UNCHANGED.copy())
317318
# cleanup temp dir
318319
logging.info("Cleaning up temp directory...")
319-
recursive_delete("/tmp/zypperoni")
320+
recursive_delete(ZYPPERONI_TMP_DIR)
320321
# release zypper exclusive lock
321322
release_zypp_lock()
322323
# perform additional zypper commands (if any) on no exception
@@ -438,15 +439,13 @@ if os.path.isfile(ZYPPER_PID_FILE):
438439
sys.exit(5)
439440

440441
# Create and secure temp dir
441-
tmp_dir = "/tmp/zypperoni"
442-
if os.path.exists(tmp_dir):
443-
os.rename(tmp_dir, f"{tmp_dir}.{int(time.time())}.broken")
444-
else:
445-
commands = f"""
446-
mkdir -p {tmp_dir};
447-
chmod 700 {tmp_dir};
442+
if os.path.exists(ZYPPERONI_TMP_DIR):
443+
os.rename(ZYPPERONI_TMP_DIR, f"{ZYPPERONI_TMP_DIR}.{int(time.time())}.broken")
444+
commands = f"""
445+
mkdir -p {ZYPPERONI_TMP_DIR};
446+
chmod 700 {ZYPPERONI_TMP_DIR};
448447
"""
449-
shell_exec(commands)
448+
shell_exec(commands)
450449

451450
# Handle commands: ref, force-ref
452451
if COMMAND in ["ref", "force-ref"]:
@@ -463,6 +462,7 @@ if COMMAND in ["ref", "force-ref"]:
463462
if not REPO_ALIAS:
464463
logging.info("No repos found. Exiting...")
465464
release_zypp_lock()
465+
recursive_delete(ZYPPERONI_TMP_DIR)
466466
sys.exit()
467467
try:
468468
asyncio.run(main_task(MAX_JOBS, COMMAND, REPO_ALIAS))
@@ -502,21 +502,26 @@ elif COMMAND in ["dup", "dup-download"]:
502502
if not DUP_PKG:
503503
logging.info("Nothing to do. Exiting...")
504504
release_zypp_lock()
505+
recursive_delete(ZYPPERONI_TMP_DIR)
505506
sys.exit()
506507
# do not download if all packages are already in cache
507508
if COMMAND == "dup-download" and download_size_bytes == 0:
508509
logging.info("Nothing to do. Exiting...")
509510
release_zypp_lock()
511+
recursive_delete(ZYPPERONI_TMP_DIR)
510512
sys.exit()
511513
# proceed straight to dup if all packages are in cache
512514
if COMMAND == "dup" and download_size_bytes == 0:
513515
release_zypp_lock()
516+
recursive_delete(ZYPPERONI_TMP_DIR)
514517
logging.info("Zypperoni has finished its tasks. Handing you over to zypper...")
515518
command = f"env ZYPP_SINGLE_RPMTRANS=1 zypper {'--non-interactive' if NO_CONFIRM else ''} dist-upgrade"
516519
os.system(command)
517520
sys.exit()
518521
logging.info(f"Packages to download: {' '.join(DUP_PKG)}")
519522
if not NO_CONFIRM and not query_yes_no("Would you like to continue?", default="yes"):
523+
release_zypp_lock()
524+
recursive_delete(ZYPPERONI_TMP_DIR)
520525
sys.exit()
521526
try:
522527
asyncio.run(main_task(MAX_JOBS, COMMAND, DUP_PKG, NO_CONFIRM))
@@ -547,6 +552,7 @@ elif COMMAND in ["in", "in-download"]:
547552
friendly_output += item.text + "\n"
548553
logging.error(f"There was an error processing your request.\n[zypper output]\n{friendly_output.strip()}")
549554
release_zypp_lock()
555+
recursive_delete(ZYPPERONI_TMP_DIR)
550556
sys.exit(6)
551557
# parse all packages from xml output
552558
IN_PKG = []
@@ -564,21 +570,26 @@ elif COMMAND in ["in", "in-download"]:
564570
if not IN_PKG:
565571
logging.info("Nothing to do. Exiting...")
566572
release_zypp_lock()
573+
recursive_delete(ZYPPERONI_TMP_DIR)
567574
sys.exit()
568575
# do not download if all packages are already in cache
569576
if COMMAND == "in-download" and download_size_bytes == 0:
570577
logging.info("Nothing to do. Exiting...")
571578
release_zypp_lock()
579+
recursive_delete(ZYPPERONI_TMP_DIR)
572580
sys.exit()
573581
# proceed straight to install if all packages are in cache
574582
if COMMAND == "in" and download_size_bytes == 0:
575583
release_zypp_lock()
584+
recursive_delete(ZYPPERONI_TMP_DIR)
576585
logging.info("Zypperoni has finished its tasks. Handing you over to zypper...")
577586
command = f"env ZYPP_SINGLE_RPMTRANS=1 zypper {'--non-interactive' if NO_CONFIRM else ''} install {' '.join(ARG)}"
578587
os.system(command)
579588
sys.exit()
580589
logging.info(f"Packages to download: {' '.join(IN_PKG)}")
581590
if not NO_CONFIRM and not query_yes_no("Would you like to continue?", default="yes"):
591+
release_zypp_lock()
592+
recursive_delete(ZYPPERONI_TMP_DIR)
582593
sys.exit()
583594
try:
584595
asyncio.run(main_task(MAX_JOBS, COMMAND, IN_PKG, NO_CONFIRM))
@@ -617,21 +628,26 @@ elif COMMAND in ["inr", "inr-download"]:
617628
if not INR_PKG:
618629
logging.info("Nothing to do. Exiting...")
619630
release_zypp_lock()
631+
recursive_delete(ZYPPERONI_TMP_DIR)
620632
sys.exit()
621633
# do not download if all packages are already in cache
622634
if COMMAND == "inr-download" and download_size_bytes == 0:
623635
logging.info("Nothing to do. Exiting...")
624636
release_zypp_lock()
637+
recursive_delete(ZYPPERONI_TMP_DIR)
625638
sys.exit()
626639
# proceed straight to inr if all packages are in cache
627640
if COMMAND == "inr" and download_size_bytes == 0:
628641
release_zypp_lock()
642+
recursive_delete(ZYPPERONI_TMP_DIR)
629643
logging.info("Zypperoni has finished its tasks. Handing you over to zypper...")
630644
command = f"env ZYPP_SINGLE_RPMTRANS=1 zypper {'--non-interactive' if NO_CONFIRM else ''} install-new-recommends"
631645
os.system(command)
632646
sys.exit()
633647
logging.info(f"Packages to download: {' '.join(INR_PKG)}")
634648
if not NO_CONFIRM and not query_yes_no("Would you like to continue?", default="yes"):
649+
release_zypp_lock()
650+
recursive_delete(ZYPPERONI_TMP_DIR)
635651
sys.exit()
636652
try:
637653
asyncio.run(main_task(MAX_JOBS, COMMAND, INR_PKG, NO_CONFIRM))

0 commit comments

Comments
 (0)