@@ -27,7 +27,8 @@ from shlex import quote
2727import 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"
3132ZYPPER_PID_FILE = "/run/zypp.pid"
3233VALID_CMD = ["ref" , "force-ref" , "in" , "in-download" , "dup" , "dup-download" , "inr" , "inr-download" ]
3334VALID_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;
6869if 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")";
7374fi;
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;
9495if 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")";
99100fi;
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
178179def 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
452451if 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