| @@ -14,8 +14,6 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import time |  | ||||||
|  |  | ||||||
| from devstack import component as comp | from devstack import component as comp | ||||||
| from devstack import exceptions as excp | from devstack import exceptions as excp | ||||||
| from devstack import log as logging | from devstack import log as logging | ||||||
| @@ -248,7 +246,7 @@ class DBRuntime(comp.EmptyRuntime): | |||||||
|                 run_as_root=True, |                 run_as_root=True, | ||||||
|                 check_exit_code=True) |                 check_exit_code=True) | ||||||
|             LOG.info("Please wait %s seconds while it starts up." % START_WAIT_TIME) |             LOG.info("Please wait %s seconds while it starts up." % START_WAIT_TIME) | ||||||
|             time.sleep(START_WAIT_TIME) |             sh.sleep(START_WAIT_TIME) | ||||||
|             return 1 |             return 1 | ||||||
|         else: |         else: | ||||||
|             return 0 |             return 0 | ||||||
| @@ -270,7 +268,7 @@ class DBRuntime(comp.EmptyRuntime): | |||||||
|                         run_as_root=True, |                         run_as_root=True, | ||||||
|                         check_exit_code=True) |                         check_exit_code=True) | ||||||
|         LOG.info("Please wait %s seconds while it restarts." % START_WAIT_TIME) |         LOG.info("Please wait %s seconds while it restarts." % START_WAIT_TIME) | ||||||
|         time.sleep(START_WAIT_TIME) |         sh.sleep(START_WAIT_TIME) | ||||||
|         return 1 |         return 1 | ||||||
|  |  | ||||||
|     def status(self): |     def status(self): | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ | |||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import io | import io | ||||||
| import time |  | ||||||
|  |  | ||||||
| from devstack import cfg | from devstack import cfg | ||||||
| from devstack import component as comp | from devstack import component as comp | ||||||
| @@ -224,5 +223,5 @@ class GlanceRuntime(comp.PythonRuntime): | |||||||
|             #install any images that need activating... |             #install any images that need activating... | ||||||
|             # TODO: make this less cheesy - need to wait till glance goes online |             # TODO: make this less cheesy - need to wait till glance goes online | ||||||
|             LOG.info("Waiting %s seconds so that glance can start up before image install." % (WAIT_ONLINE_TO)) |             LOG.info("Waiting %s seconds so that glance can start up before image install." % (WAIT_ONLINE_TO)) | ||||||
|             time.sleep(WAIT_ONLINE_TO) |             sh.sleep(WAIT_ONLINE_TO) | ||||||
|             creator.ImageCreationService(self.cfg).install() |             creator.ImageCreationService(self.cfg).install() | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ | |||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import io | import io | ||||||
| import time |  | ||||||
|  |  | ||||||
| from urlparse import urlunparse | from urlparse import urlunparse | ||||||
|  |  | ||||||
| @@ -224,7 +223,7 @@ class KeystoneRuntime(comp.PythonRuntime): | |||||||
|             #these environment additions are important |             #these environment additions are important | ||||||
|             #in that they eventually affect how this script runs |             #in that they eventually affect how this script runs | ||||||
|             LOG.info("Waiting %s seconds so that keystone can start up before running first time init." % (WAIT_ONLINE_TO)) |             LOG.info("Waiting %s seconds so that keystone can start up before running first time init." % (WAIT_ONLINE_TO)) | ||||||
|             time.sleep(WAIT_ONLINE_TO) |             sh.sleep(WAIT_ONLINE_TO) | ||||||
|             env = dict() |             env = dict() | ||||||
|             env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) |             env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) | ||||||
|             env['BIN_DIR'] = self.bindir |             env['BIN_DIR'] = self.bindir | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ | |||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import io | import io | ||||||
| import time |  | ||||||
|  |  | ||||||
| from devstack import cfg | from devstack import cfg | ||||||
| from devstack import component as comp | from devstack import component as comp | ||||||
| @@ -169,7 +168,7 @@ class MelangeRuntime(comp.PythonRuntime): | |||||||
|         comp.PythonRuntime.post_start(self) |         comp.PythonRuntime.post_start(self) | ||||||
|         if CREATE_CIDR in self.component_opts or not self.component_opts: |         if CREATE_CIDR in self.component_opts or not self.component_opts: | ||||||
|             LOG.info("Waiting %s seconds so that the melange server can start up before cidr range creation." % (WAIT_ONLINE_TO)) |             LOG.info("Waiting %s seconds so that the melange server can start up before cidr range creation." % (WAIT_ONLINE_TO)) | ||||||
|             time.sleep(WAIT_ONLINE_TO) |             sh.sleep(WAIT_ONLINE_TO) | ||||||
|             mp = dict() |             mp = dict() | ||||||
|             mp['CIDR_RANGE'] = self.cfg.getdefaulted('melange', 'm_mac_range', DEF_CIDR_RANGE) |             mp['CIDR_RANGE'] = self.cfg.getdefaulted('melange', 'm_mac_range', DEF_CIDR_RANGE) | ||||||
|             utils.execute_template(*CIDR_CREATE_CMD, params=mp) |             utils.execute_template(*CIDR_CREATE_CMD, params=mp) | ||||||
|   | |||||||
| @@ -17,7 +17,6 @@ | |||||||
| from urlparse import urlunparse | from urlparse import urlunparse | ||||||
|  |  | ||||||
| import os | import os | ||||||
| import time |  | ||||||
|  |  | ||||||
| from devstack import component as comp | from devstack import component as comp | ||||||
| from devstack import date | from devstack import date | ||||||
| @@ -443,7 +442,7 @@ class NovaRuntime(comp.PythonRuntime): | |||||||
|             #in that they eventually affect how this script runs |             #in that they eventually affect how this script runs | ||||||
|             if utils.service_enabled(settings.QUANTUM, self.instances, False): |             if utils.service_enabled(settings.QUANTUM, self.instances, False): | ||||||
|                 LOG.info("Waiting %s seconds so that quantum can start up before running first time init." % (WAIT_ONLINE_TO)) |                 LOG.info("Waiting %s seconds so that quantum can start up before running first time init." % (WAIT_ONLINE_TO)) | ||||||
|                 time.sleep(WAIT_ONLINE_TO) |                 sh.sleep(WAIT_ONLINE_TO) | ||||||
|             env = dict() |             env = dict() | ||||||
|             env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) |             env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) | ||||||
|             setup_cmd = NET_INIT_CMD_ROOT + [tgt_fn] |             setup_cmd = NET_INIT_CMD_ROOT + [tgt_fn] | ||||||
| @@ -833,7 +832,7 @@ class NovaConfConfigurator(object): | |||||||
|         LOG.debug("Attempting to create instance directory: %s" % (instances_path)) |         LOG.debug("Attempting to create instance directory: %s" % (instances_path)) | ||||||
|         self.tracewriter.dirs_made(*sh.mkdirslist(instances_path)) |         self.tracewriter.dirs_made(*sh.mkdirslist(instances_path)) | ||||||
|         LOG.debug("Adjusting permissions of instance directory: %s" % (instances_path)) |         LOG.debug("Adjusting permissions of instance directory: %s" % (instances_path)) | ||||||
|         os.chmod(instances_path, 0777) |         sh.chmod(instances_path, 0777) | ||||||
|  |  | ||||||
|     def _configure_libvirt(self, virt_type, nova_conf): |     def _configure_libvirt(self, virt_type, nova_conf): | ||||||
|         if virt_type == 'lxc': |         if virt_type == 'lxc': | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ | |||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| from tempfile import TemporaryFile | from tempfile import TemporaryFile | ||||||
| import time |  | ||||||
|  |  | ||||||
| from devstack import component as comp | from devstack import component as comp | ||||||
| from devstack import log as logging | from devstack import log as logging | ||||||
| @@ -133,7 +132,7 @@ class RabbitRuntime(comp.EmptyRuntime): | |||||||
|         LOG.info("Restarting rabbit-mq.") |         LOG.info("Restarting rabbit-mq.") | ||||||
|         self._run_cmd(RESTART_CMD) |         self._run_cmd(RESTART_CMD) | ||||||
|         LOG.info("Please wait %s seconds while it starts up." % (WAIT_ON_TIME)) |         LOG.info("Please wait %s seconds while it starts up." % (WAIT_ON_TIME)) | ||||||
|         time.sleep(WAIT_ON_TIME) |         sh.sleep(WAIT_ON_TIME) | ||||||
|         return 1 |         return 1 | ||||||
|  |  | ||||||
|     def stop(self): |     def stop(self): | ||||||
|   | |||||||
| @@ -14,8 +14,6 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import time |  | ||||||
|  |  | ||||||
| from devstack import exceptions as excp | from devstack import exceptions as excp | ||||||
| from devstack import log as logging | from devstack import log as logging | ||||||
| from devstack import settings | from devstack import settings | ||||||
| @@ -110,7 +108,7 @@ def restart(distro): | |||||||
|         mp['SERVICE'] = SV_NAME_MAP[distro] |         mp['SERVICE'] = SV_NAME_MAP[distro] | ||||||
|         utils.execute_template(*cmds, params=mp) |         utils.execute_template(*cmds, params=mp) | ||||||
|         LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME)) |         LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME)) | ||||||
|         time.sleep(WAIT_ALIVE_TIME) |         sh.sleep(WAIT_ALIVE_TIME) | ||||||
|  |  | ||||||
|  |  | ||||||
| def virt_ok(virt_type, distro): | def virt_ok(virt_type, distro): | ||||||
|   | |||||||
| @@ -49,6 +49,12 @@ def parse(): | |||||||
|         dest="verbosity", |         dest="verbosity", | ||||||
|         default=[1], |         default=[1], | ||||||
|         help="increase the verbose level") |         help="increase the verbose level") | ||||||
|  |     parser.add_option("", "--dryrun", | ||||||
|  |         action="store_const", | ||||||
|  |         const=1, | ||||||
|  |         dest="dryrun", | ||||||
|  |         default=0, | ||||||
|  |         help="log actions without actually doing any of them") | ||||||
|  |  | ||||||
|     base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options") |     base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options") | ||||||
|     base_group.add_option("-a", "--action", |     base_group.add_option("-a", "--action", | ||||||
| @@ -104,6 +110,7 @@ def parse(): | |||||||
|     output = dict() |     output = dict() | ||||||
|     output['components'] = options.component or list() |     output['components'] = options.component or list() | ||||||
|     output['dir'] = options.dir or "" |     output['dir'] = options.dir or "" | ||||||
|  |     output['dryrun'] = options.dryrun or False | ||||||
|     output['ref_components'] = options.ref_components or list() |     output['ref_components'] = options.ref_components or list() | ||||||
|     output['action'] = options.action or "" |     output['action'] = options.action or "" | ||||||
|     output['force'] = not options.force |     output['force'] = not options.force | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ import subprocess | |||||||
| import sys | import sys | ||||||
| import random | import random | ||||||
| import re | import re | ||||||
|  | import time | ||||||
|  |  | ||||||
| from devstack import env | from devstack import env | ||||||
| from devstack import exceptions as excp | from devstack import exceptions as excp | ||||||
| @@ -44,6 +45,13 @@ SHELL_QUOTE_REPLACERS = { | |||||||
| SHELL_WRAPPER = "\"%s\"" | SHELL_WRAPPER = "\"%s\"" | ||||||
| ROOT_PATH = os.sep | ROOT_PATH = os.sep | ||||||
| RANDOMIZER = random.SystemRandom() | RANDOMIZER = random.SystemRandom() | ||||||
|  | DRYRUN = None | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def set_dryrun(val): | ||||||
|  |     global DRYRUN | ||||||
|  |     LOG.info("Setting dryrun to:%s" % (val)) | ||||||
|  |     DRYRUN = val | ||||||
|  |  | ||||||
|  |  | ||||||
| #root context guard | #root context guard | ||||||
| @@ -65,7 +73,6 @@ class Rooted(object): | |||||||
|  |  | ||||||
|  |  | ||||||
| def execute(*cmd, **kwargs): | def execute(*cmd, **kwargs): | ||||||
|  |  | ||||||
|     process_input = kwargs.pop('process_input', None) |     process_input = kwargs.pop('process_input', None) | ||||||
|     check_exit_code = kwargs.pop('check_exit_code', [0]) |     check_exit_code = kwargs.pop('check_exit_code', [0]) | ||||||
|     cwd = kwargs.pop('cwd', None) |     cwd = kwargs.pop('cwd', None) | ||||||
| @@ -129,6 +136,11 @@ def execute(*cmd, **kwargs): | |||||||
|     rc = None |     rc = None | ||||||
|     result = None |     result = None | ||||||
|     with Rooted(run_as_root): |     with Rooted(run_as_root): | ||||||
|  |         if DRYRUN: | ||||||
|  |             LOG.info("DRYRUN:%s" % (execute_cmd)) | ||||||
|  |             # Pretend it worked | ||||||
|  |             rc = 0 | ||||||
|  |         else: | ||||||
|             try: |             try: | ||||||
|                 obj = subprocess.Popen(execute_cmd, |                 obj = subprocess.Popen(execute_cmd, | ||||||
|                                        stdin=stdin_fh, |                                        stdin=stdin_fh, | ||||||
| @@ -343,6 +355,10 @@ def mkdirslist(path): | |||||||
|  |  | ||||||
|  |  | ||||||
| def append_file(fn, text, flush=True, quiet=False): | def append_file(fn, text, flush=True, quiet=False): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN append_file:%s" % (fn)) | ||||||
|  |         LOG.info("%s" % (text)) | ||||||
|  |         return fn | ||||||
|     if not quiet: |     if not quiet: | ||||||
|         LOG.debug("Appending to file %s (%d bytes)", fn, len(text)) |         LOG.debug("Appending to file %s (%d bytes)", fn, len(text)) | ||||||
|     with open(fn, "a") as f: |     with open(fn, "a") as f: | ||||||
| @@ -353,6 +369,10 @@ def append_file(fn, text, flush=True, quiet=False): | |||||||
|  |  | ||||||
|  |  | ||||||
| def write_file(fn, text, flush=True, quiet=False): | def write_file(fn, text, flush=True, quiet=False): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN write_file:%s" % (fn)) | ||||||
|  |         LOG.info("%s" % (text)) | ||||||
|  |         return fn | ||||||
|     if not quiet: |     if not quiet: | ||||||
|         LOG.debug("Writing to file %s (%d bytes)", fn, len(text)) |         LOG.debug("Writing to file %s (%d bytes)", fn, len(text)) | ||||||
|     with open(fn, "w") as f: |     with open(fn, "w") as f: | ||||||
| @@ -363,6 +383,9 @@ def write_file(fn, text, flush=True, quiet=False): | |||||||
|  |  | ||||||
|  |  | ||||||
| def touch_file(fn, die_if_there=True, quiet=False, file_size=0): | def touch_file(fn, die_if_there=True, quiet=False, file_size=0): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN touch_file:%s" % (fn)) | ||||||
|  |         return fn | ||||||
|     if not isfile(fn): |     if not isfile(fn): | ||||||
|         if not quiet: |         if not quiet: | ||||||
|             LOG.debug("Touching and truncating file %s (%s)", fn, file_size) |             LOG.debug("Touching and truncating file %s (%s)", fn, file_size) | ||||||
| @@ -376,16 +399,30 @@ def touch_file(fn, die_if_there=True, quiet=False, file_size=0): | |||||||
|  |  | ||||||
|  |  | ||||||
| def load_file(fn, quiet=False): | def load_file(fn, quiet=False): | ||||||
|  |     LOG.info("load_file:%s" % (fn)) | ||||||
|     if not quiet: |     if not quiet: | ||||||
|         LOG.debug("Loading data from file %s", fn) |         LOG.debug("Loading data from file %s", fn) | ||||||
|  |     try: | ||||||
|         with open(fn, "r") as f: |         with open(fn, "r") as f: | ||||||
|             data = f.read() |             data = f.read() | ||||||
|  |     except IOError as e: | ||||||
|  |         # If there was an error, then check if we're doing a dryrun. If | ||||||
|  |         # yes, then return no data, otherwise the the error bubble on up | ||||||
|  |         if DRYRUN: | ||||||
|  |             LOG.info("DRYRUN: return no data for load_file:%s" % (fn)) | ||||||
|  |             data = "" | ||||||
|  |         else: | ||||||
|  |             raise e | ||||||
|  |  | ||||||
|     if not quiet: |     if not quiet: | ||||||
|         LOG.debug("Loaded (%d) bytes from file %s", len(data), fn) |         LOG.debug("Loaded (%d) bytes from file %s", len(data), fn) | ||||||
|     return data |     return data | ||||||
|  |  | ||||||
|  |  | ||||||
| def mkdir(path, recurse=True): | def mkdir(path, recurse=True): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN mkdir:%s" % (path)) | ||||||
|  |         return | ||||||
|     if not isdir(path): |     if not isdir(path): | ||||||
|         if recurse: |         if recurse: | ||||||
|             LOG.debug("Recursively creating directory \"%s\"" % (path)) |             LOG.debug("Recursively creating directory \"%s\"" % (path)) | ||||||
| @@ -396,6 +433,9 @@ def mkdir(path, recurse=True): | |||||||
|  |  | ||||||
|  |  | ||||||
| def deldir(path, run_as_root=False): | def deldir(path, run_as_root=False): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN deldir:%s" % (path)) | ||||||
|  |         return | ||||||
|     with Rooted(run_as_root): |     with Rooted(run_as_root): | ||||||
|         if isdir(path): |         if isdir(path): | ||||||
|             LOG.debug("Recursively deleting directory tree starting at \"%s\"" % (path)) |             LOG.debug("Recursively deleting directory tree starting at \"%s\"" % (path)) | ||||||
| @@ -403,6 +443,9 @@ def deldir(path, run_as_root=False): | |||||||
|  |  | ||||||
|  |  | ||||||
| def rmdir(path, quiet=True, run_as_root=False): | def rmdir(path, quiet=True, run_as_root=False): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN rmdir:%s" % (path)) | ||||||
|  |         return | ||||||
|     if not isdir(path): |     if not isdir(path): | ||||||
|         return |         return | ||||||
|     try: |     try: | ||||||
| @@ -422,6 +465,9 @@ def symlink(source, link, force=True, run_as_root=True): | |||||||
|         LOG.debug("Creating symlink from %s => %s" % (link, source)) |         LOG.debug("Creating symlink from %s => %s" % (link, source)) | ||||||
|         path = dirname(link) |         path = dirname(link) | ||||||
|         needed_pths = mkdirslist(path) |         needed_pths = mkdirslist(path) | ||||||
|  |         if DRYRUN: | ||||||
|  |             LOG.info("DRYRUN symlink from %s => %s" % (source, link)) | ||||||
|  |         else: | ||||||
|             if force and (exists(link) or islink(link)): |             if force and (exists(link) or islink(link)): | ||||||
|                 unlink(link, True) |                 unlink(link, True) | ||||||
|             os.symlink(source, link) |             os.symlink(source, link) | ||||||
| @@ -534,6 +580,9 @@ def umount(dev_name, ignore_errors=True): | |||||||
|  |  | ||||||
|  |  | ||||||
| def unlink(path, ignore_errors=True, run_as_root=False): | def unlink(path, ignore_errors=True, run_as_root=False): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN unlink:%s" % (path)) | ||||||
|  |         return | ||||||
|     try: |     try: | ||||||
|         LOG.debug("Unlinking (removing) %s" % (path)) |         LOG.debug("Unlinking (removing) %s" % (path)) | ||||||
|         with Rooted(run_as_root): |         with Rooted(run_as_root): | ||||||
| @@ -546,10 +595,16 @@ def unlink(path, ignore_errors=True, run_as_root=False): | |||||||
|  |  | ||||||
|  |  | ||||||
| def move(src, dst): | def move(src, dst): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN move:%s" % (src, dst)) | ||||||
|  |         return | ||||||
|     shutil.move(src, dst) |     shutil.move(src, dst) | ||||||
|  |  | ||||||
|  |  | ||||||
| def chmod(fname, mode): | def chmod(fname, mode): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN chmod:%s to %s" % (fname, mode)) | ||||||
|  |         return | ||||||
|     os.chmod(fname, mode) |     os.chmod(fname, mode) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -567,6 +622,9 @@ def replace_in(fn, search, replace, run_as_root=False): | |||||||
|  |  | ||||||
| def copy_replace_file(fsrc, fdst, linemap): | def copy_replace_file(fsrc, fdst, linemap): | ||||||
|     files = mkdirslist(dirname(fdst)) |     files = mkdirslist(dirname(fdst)) | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN copy_replace:%s" % (fsrc, fdst)) | ||||||
|  |         return | ||||||
|     with open(fdst, 'w') as fh: |     with open(fdst, 'w') as fh: | ||||||
|         for line in fileinput.input(fsrc): |         for line in fileinput.input(fsrc): | ||||||
|             for (k, v) in linemap.items(): |             for (k, v) in linemap.items(): | ||||||
| @@ -626,3 +684,10 @@ def geteuid(): | |||||||
|  |  | ||||||
| def getegid(): | def getegid(): | ||||||
|     return os.getegid() |     return os.getegid() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def sleep(winks): | ||||||
|  |     if DRYRUN: | ||||||
|  |         LOG.info("DRYRUN, sleep for:%s" % (winks)) | ||||||
|  |     else: | ||||||
|  |         time.sleep(winks) | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								stack
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								stack
									
									
									
									
									
								
							| @@ -93,6 +93,10 @@ def run(args): | |||||||
|     #here on out we should be using the logger (and not print) |     #here on out we should be using the logger (and not print) | ||||||
|     start_time = time.time() |     start_time = time.time() | ||||||
|     config = common.get_config() |     config = common.get_config() | ||||||
|  |     # Stash the dryrun value (if any) into the global configuration | ||||||
|  |     dryrun = args.get('dryrun') | ||||||
|  |     if dryrun: | ||||||
|  |         sh.set_dryrun(dryrun) | ||||||
|     pkg_manager = common.get_packager(distro, args.get('keep_old')) |     pkg_manager = common.get_packager(distro, args.get('keep_old')) | ||||||
|     components = utils.parse_components(args.pop("components")) |     components = utils.parse_components(args.pop("components")) | ||||||
|     runner = actions.ActionRunner(distro, action, rootdir, config, pkg_manager, components=components, **args) |     runner = actions.ActionRunner(distro, action, rootdir, config, pkg_manager, components=components, **args) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ken Thomas
					Ken Thomas