import os.path import sys from subprocess import Popen, PIPE from time import sleep from cobbler_set_netboot_enabled import cobbler_set_netboot_enabled from set_bootdev_clients import set_bootdev_clients from set_power_clients import set_power_clients from lib.config import Config from lib.inventory import Inventory import lib.logger as logger import lib.genesis as gen POWER_TIME_OUT = gen.get_power_time_out() POWER_WAIT = gen.get_power_wait() IS_CONTAINER = gen.is_container() def _sub_proc_exec(cmd): data = Popen(cmd.split(), stdout=PIPE, stderr=PIPE) stdout, stderr = data.communicate() return stdout.decode("utf-8"), stderr.decode("utf-8") def _get_lists(latest_list, handled_list): """Keeps track of clients which have had their bootdev reset to 'default' inputs: latest_list: (list) List of ip addresses from the latest cobbler status returns: those client ip addreses that are newly found in new_list, and the cumulative list of those clients which have been handled in handled_list """
def launch(self): """Launch actions""" cmd = None if not hasattr(self.args, 'software'): self.cont_config_file_path += (os.path.basename( self.args.config_file_name)) path = self.args.config_file_name if os.path.dirname(self.args.config_file_name) == '': path = os.path.join(os.getcwd(), self.args.config_file_name) if os.path.isfile(path): self.config_file_path = path else: self.config_file_path += self.args.config_file_name if (not hasattr(self.args, 'osinstall') and not os.path.isfile(self.config_file_path) ) and not (hasattr(self.args, "bundle_to") or hasattr(self.args, 'bundle_from')): print('{} not found. Please specify a file name'.format( self.config_file_path)) sys.exit(1) self.config_file_path = os.path.abspath(self.config_file_path) # Determine which subcommand was specified try: if self.args.setup: cmd = argparse_gen.Cmd.SETUP.value except AttributeError: pass try: if self.args.config: cmd = argparse_gen.Cmd.CONFIG.value except AttributeError: pass try: if self.args.validate: cmd = argparse_gen.Cmd.VALIDATE.value print('\nUsing {}'.format(self.config_file_path)) resp = input('Enter to continue. "T" to terminate ') if resp == 'T': sys.exit('POWER-Up stopped at user request') except AttributeError: pass try: if self.args.deploy: cmd = argparse_gen.Cmd.DEPLOY.value except AttributeError: pass try: if self.args.post_deploy: cmd = argparse_gen.Cmd.POST_DEPLOY.value except AttributeError: pass try: if self.args.osinstall: cmd = argparse_gen.Cmd.OSINSTALL.value except AttributeError: pass try: if self.args.software: cmd = argparse_gen.Cmd.SOFTWARE.value except AttributeError: pass try: if self.args.utils: cmd = argparse_gen.Cmd.UTIL.value except AttributeError: pass # Invoke subcommand method if cmd == argparse_gen.Cmd.SETUP.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) self._check_root_user(cmd) if self.args.all: self.args.networks = True self.args.gateway = True if self.args.networks: self._create_deployer_networks() if self.args.gateway: self._enable_deployer_gateway() if cmd == argparse_gen.Cmd.CONFIG.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.create_container): self._check_non_root_user(cmd) self._create_container() if self.args.mgmt_switches: self._config_mgmt_switches() if argparse_gen.is_arg_present(self.args.data_switches): self._config_data_switches() if cmd == argparse_gen.Cmd.VALIDATE.value: if argparse_gen.is_arg_present(self.args.config_file): self._check_non_root_user(cmd) self._config_file() if argparse_gen.is_arg_present(self.args.cluster_hardware): self._check_root_user(cmd) self._cluster_hardware() if cmd == argparse_gen.Cmd.DEPLOY.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.all): self.args.create_inventory = self.args.all self.args.install_cobbler = self.args.all self.args.download_os_images = self.args.all self.args.inv_add_ports_ipmi = self.args.all self.args.inv_add_ports_pxe = self.args.all self.args.reserve_ipmi_pxe_ips = self.args.all self.args.add_cobbler_distros = self.args.all self.args.add_cobbler_systems = self.args.all self.args.install_client_os = self.args.all if argparse_gen.is_arg_present(self.args.create_inventory): self._create_inventory() if argparse_gen.is_arg_present(self.args.install_cobbler): self._install_cobbler() if argparse_gen.is_arg_present(self.args.download_os_images): self._download_os_images() if argparse_gen.is_arg_present(self.args.inv_add_ports_ipmi): self._inv_add_ports_ipmi() if argparse_gen.is_arg_present(self.args.inv_add_ports_pxe): self._inv_add_ports_pxe() if argparse_gen.is_arg_present(self.args.reserve_ipmi_pxe_ips): self._reserve_ipmi_pxe_ips() if argparse_gen.is_arg_present(self.args.add_cobbler_distros): self._add_cobbler_distros() if argparse_gen.is_arg_present(self.args.add_cobbler_systems): self._add_cobbler_systems() if argparse_gen.is_arg_present(self.args.install_client_os): self._install_client_os() if argparse_gen.is_arg_present(self.args.all): print("\n\nPress enter to continue with node configuration ") print("and data switch setup, or 'T' to terminate ") print("POWER-Up. (To restart, type: 'pup post-deploy)") resp = input("\nEnter or 'T': ") if resp == 'T': sys.exit('POWER-Up stopped at user request') cmd = argparse_gen.Cmd.POST_DEPLOY.value if cmd == argparse_gen.Cmd.POST_DEPLOY.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.all): self.args.ssh_keyscan = self.args.all self.args.gather_mac_addr = self.args.all self.args.data_switches = self.args.all self.args.lookup_interface_names = self.args.all self.args.config_client_os = self.args.all self._validate_bootstrap_vars() if argparse_gen.is_arg_present(self.args.ssh_keyscan): self._ssh_keyscan() if argparse_gen.is_arg_present(self.args.gather_mac_addr): self._gather_mac_addr() if argparse_gen.is_arg_present(self.args.lookup_interface_names): self._lookup_interface_names() if argparse_gen.is_arg_present(self.args.config_client_os): self._config_client_os() if argparse_gen.is_arg_present(self.args.all): self._config_data_switches() if cmd == argparse_gen.Cmd.OSINSTALL.value: self._osinstall() if cmd == argparse_gen.Cmd.SOFTWARE.value: if not argparse_gen.is_arg_present(self.args.prep) and not \ argparse_gen.is_arg_present(self.args.init_clients) and not \ argparse_gen.is_arg_present(self.args.install) and not \ argparse_gen.is_arg_present(self.args.README) and not \ argparse_gen.is_arg_present(self.args.status) and not \ argparse_gen.is_arg_present(self.args.bundle_to) and not \ argparse_gen.is_arg_present(self.args.extract_from) and not \ argparse_gen.is_arg_present(self.args.extract_from) and not \ argparse_gen.is_arg_present(self.args.download_install_deps): self.args.all = True if self.args.bundle_to or self.args.extract_from: self.args.all = False if gen.GEN_SOFTWARE_PATH not in sys.path: sys.path.append(gen.GEN_SOFTWARE_PATH) try: self.args.name = self.args.name.split('.')[0] software_module = importlib.import_module(self.args.name) except ImportError as exc: print(exc) sys.exit(1) if 'software' not in dir(software_module): self.log.error( 'Software installation modules need to implement a ' 'class named "software"') sys.exit(1) else: soft = software_module.software( self.args.eval, self.args.non_interactive, self.args.arch, self.args.proc_family, self.args.engr_mode, self.args.base_dir, self.args.public) if self.args.bundle_to: try: self._bundle(soft.root_dir) except: sys.exit(1) if self.args.extract_from: log = logger.getlogger() try: in_dir = bundle.validate_directories( soft.root_dir, self.args.extract_from[0]) if in_dir is not None: msg = 'Directories exist in {0} directory and will be overwritten\nDirectories: \n\t{1}'.format( soft.root_dir, "\n\t".join(in_dir)) log.warning(msg) while True: try: resp = input( "Enter C to continue extracting or 'T' to terminate \n" ) if resp == 'T': log.info( "'{}' entered. Terminating POWER-Up at user request" .format(resp)) sys.exit(1) elif resp == 'C': log.info( "'{0}' entered. Continuing archiving of {1}" .format(resp, soft.root_dir)) break else: continue except KeyboardInterrupt: log.info("\nExiting at user request ... ") sys.exit(1) except Exception as e: log.error("Uncaught exception:\n{0}".format(e)) sys.exit(1) self._extract_bundle(soft.root_dir) else: self._extract_bundle(soft.root_dir) except Exception as e: print(e) sys.exit(1) try: if (self.args.prep is True or self.args.all is True) and self.args.step is not None: try: soft.prep_init() for step in self.args.step: run_this = "create_" + step if hasattr(soft, run_this): func = getattr(soft, run_this) func() else: print('\nUnable to find: ' + step + " in :" + self.args.name) soft.prep_post() except AttributeError as exc: print(exc) elif (self.args.prep is True or self.args.all is True) and self.args.step is None: try: soft.prep() except AttributeError as exc: print(exc.message) print('The software class needs to implement a ' 'method named "setup"') except KeyboardInterrupt as e: soft.prep_post() print('User exited ...\n' + str(e)) except Exception as e: raise e if self.args.init_clients is True or self.args.all is True: try: soft.init_clients() except AttributeError as exc: print(exc) print('The software class needs to implement a ' 'method named "init_clients"') try: if (self.args.install is True or self.args.all is True ) and self.args.run_ansible_task is not None: try: run_this = "run_ansible_task" import tempfile run_it_file = "" for task in self.args.run_ansible_task: task_file = soft.get_software_path( os.path.basename(task)) if not os.path.isfile(task_file): print('\nUnable to find: ' + task_file) else: run_it_file = run_it_file + '''\n- description: Running file {0}\n tasks: {1}\n'''.format( soft.get_software_path( os.path.basename(task_file)), os.path.basename(task_file)) if hasattr(soft, run_this) and run_it_file != "": func = getattr(soft, run_this) fileobj = tempfile.NamedTemporaryFile() with open(fileobj.name, 'w') as f: f.write(run_it_file) f.seek(0) func(fileobj.name) else: if run_it_file == "": print('\nUnable to find files to run') else: print('\nUnable to find: ' + run_this + " in :" + self.args.name) except AttributeError as exc: print(exc) elif (self.args.install is True or self.args.all is True ) and self.args.run_ansible_task is None: try: soft.install() except AttributeError as exc: print(exc.message) print('The software class needs to implement a ' 'method named "setup"') except KeyboardInterrupt as e: print('User exited ...\n' + str(e)) except Exception as e: raise e if self.args.README is True: try: soft.README() except AttributeError as exc: print(exc) print('No "about" information available') if self.args.status is True: try: soft.status() except AttributeError as exc: print(exc) print('No "status" information available') if self.args.download_install_deps: soft.download_install_deps() if cmd == argparse_gen.Cmd.UTIL.value: if self.args.scan_pxe_network: self._scan_pxe_network() if self.args.scan_ipmi_network: self._scan_ipmi_network() if self.args.download_install_deps: self._download_install_deps() if self.args.bundle_to or self.args.bundle_from: self._bundle(self.args.bundle_from[0]) if not cmd: print('Unrecognized POWER-Up command')
def launch(self): """Launch actions""" cmd = None self.cont_config_file_path += os.path.basename(self.args.config_file_name) path = self.args.config_file_name if os.path.dirname(self.args.config_file_name) == '': path = os.path.join(os.getcwd(), self.args.config_file_name) if os.path.isfile(path): self.config_file_path = path else: self.config_file_path += self.args.config_file_name if not os.path.isfile(self.config_file_path): print('{} not found. Please specify a config file'.format( self.config_file_path)) sys.exit(1) self.config_file_path = os.path.abspath(self.config_file_path) # Determine which subcommand was specified try: if self.args.setup: cmd = argparse_gen.Cmd.SETUP.value except AttributeError: pass try: if self.args.config: cmd = argparse_gen.Cmd.CONFIG.value except AttributeError: pass try: if self.args.validate: cmd = argparse_gen.Cmd.VALIDATE.value print('\nUsing {}'.format(self.config_file_path)) resp = raw_input('Enter to continue. "T" to terminate ') if resp == 'T': sys.exit('POWER-Up stopped at user request') except AttributeError: pass try: if self.args.deploy: cmd = argparse_gen.Cmd.DEPLOY.value except AttributeError: pass try: if self.args.post_deploy: cmd = argparse_gen.Cmd.POST_DEPLOY.value except AttributeError: pass try: if self.args.utils: cmd = argparse_gen.Cmd.UTIL.value except AttributeError: pass # Invoke subcommand method if cmd == argparse_gen.Cmd.SETUP.value: if gen.is_container(): print( 'Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) self._check_root_user(cmd) if self.args.all: self.args.networks = True self.args.gateway = True if self.args.networks: self._create_deployer_networks() if self.args.gateway: self._enable_deployer_gateway() if cmd == argparse_gen.Cmd.CONFIG.value: if gen.is_container(): print( 'Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) self._check_non_root_user(cmd) if argparse_gen.is_arg_present(self.args.create_container): self._create_container() if self.args.mgmt_switches: self._config_mgmt_switches() if argparse_gen.is_arg_present(self.args.data_switches): self._config_data_switches() if cmd == argparse_gen.Cmd.VALIDATE.value: if argparse_gen.is_arg_present(self.args.config_file): self._check_non_root_user(cmd) self._config_file() if argparse_gen.is_arg_present(self.args.cluster_hardware): self._check_root_user(cmd) self._cluster_hardware() if cmd == argparse_gen.Cmd.DEPLOY.value: if gen.is_container(): print( 'Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.all): self.args.create_inventory = self.args.all self.args.install_cobbler = self.args.all self.args.download_os_images = self.args.all self.args.inv_add_ports_ipmi = self.args.all self.args.inv_add_ports_pxe = self.args.all self.args.reserve_ipmi_pxe_ips = self.args.all self.args.add_cobbler_distros = self.args.all self.args.add_cobbler_systems = self.args.all self.args.install_client_os = self.args.all if argparse_gen.is_arg_present(self.args.create_inventory): self._create_inventory() if argparse_gen.is_arg_present(self.args.install_cobbler): self._install_cobbler() if argparse_gen.is_arg_present(self.args.download_os_images): self._download_os_images() if argparse_gen.is_arg_present(self.args.inv_add_ports_ipmi): self._inv_add_ports_ipmi() if argparse_gen.is_arg_present(self.args.inv_add_ports_pxe): self._inv_add_ports_pxe() if argparse_gen.is_arg_present(self.args.reserve_ipmi_pxe_ips): self._reserve_ipmi_pxe_ips() if argparse_gen.is_arg_present(self.args.add_cobbler_distros): self._add_cobbler_distros() if argparse_gen.is_arg_present(self.args.add_cobbler_systems): self._add_cobbler_systems() if argparse_gen.is_arg_present(self.args.install_client_os): self._install_client_os() if argparse_gen.is_arg_present(self.args.all): print("\n\nPress enter to continue with node configuration ") print("and data switch setup, or 'T' to terminate ") print("POWER-Up. (To restart, type: 'pup post-deploy)") resp = raw_input("\nEnter or 'T': ") if resp == 'T': sys.exit('POWER-Up stopped at user request') cmd = argparse_gen.Cmd.POST_DEPLOY.value if cmd == argparse_gen.Cmd.POST_DEPLOY.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.all): self.args.ssh_keyscan = self.args.all self.args.gather_mac_addr = self.args.all self.args.data_switches = self.args.all self.args.lookup_interface_names = self.args.all self.args.config_client_os = self.args.all if argparse_gen.is_arg_present(self.args.ssh_keyscan): self._ssh_keyscan() if argparse_gen.is_arg_present(self.args.gather_mac_addr): self._gather_mac_addr() if argparse_gen.is_arg_present(self.args.lookup_interface_names): self._lookup_interface_names() if argparse_gen.is_arg_present(self.args.config_client_os): self._config_client_os() if argparse_gen.is_arg_present(self.args.all): self._config_data_switches() if cmd == argparse_gen.Cmd.UTIL.value: if self.args.scan_pxe_network: self._scan_pxe_network() if self.args.scan_ipmi_network: self._scan_ipmi_network()
def launch(self): """Launch actions""" cmd = None if not hasattr(self.args, 'software'): self.cont_config_file_path += (os.path.basename( self.args.config_file_name)) path = self.args.config_file_name if os.path.dirname(self.args.config_file_name) == '': path = os.path.join(os.getcwd(), self.args.config_file_name) if os.path.isfile(path): self.config_file_path = path else: self.config_file_path += self.args.config_file_name if not os.path.isfile(self.config_file_path): print('{} not found. Please specify a config file'.format( self.config_file_path)) sys.exit(1) self.config_file_path = os.path.abspath(self.config_file_path) # Determine which subcommand was specified try: if self.args.setup: cmd = argparse_gen.Cmd.SETUP.value except AttributeError: pass try: if self.args.config: cmd = argparse_gen.Cmd.CONFIG.value except AttributeError: pass try: if self.args.validate: cmd = argparse_gen.Cmd.VALIDATE.value print('\nUsing {}'.format(self.config_file_path)) resp = input('Enter to continue. "T" to terminate ') if resp == 'T': sys.exit('POWER-Up stopped at user request') except AttributeError: pass try: if self.args.deploy: cmd = argparse_gen.Cmd.DEPLOY.value except AttributeError: pass try: if self.args.post_deploy: cmd = argparse_gen.Cmd.POST_DEPLOY.value except AttributeError: pass try: if self.args.software: cmd = argparse_gen.Cmd.SOFTWARE.value except AttributeError: pass try: if self.args.utils: cmd = argparse_gen.Cmd.UTIL.value except AttributeError: pass # Invoke subcommand method if cmd == argparse_gen.Cmd.SETUP.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) self._check_root_user(cmd) if self.args.all: self.args.networks = True self.args.gateway = True if self.args.networks: self._create_deployer_networks() if self.args.gateway: self._enable_deployer_gateway() if cmd == argparse_gen.Cmd.CONFIG.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.create_container): self._check_non_root_user(cmd) self._create_container() if self.args.mgmt_switches: self._config_mgmt_switches() if argparse_gen.is_arg_present(self.args.data_switches): self._config_data_switches() if cmd == argparse_gen.Cmd.VALIDATE.value: if argparse_gen.is_arg_present(self.args.config_file): self._check_non_root_user(cmd) self._config_file() if argparse_gen.is_arg_present(self.args.cluster_hardware): self._check_root_user(cmd) self._cluster_hardware() if cmd == argparse_gen.Cmd.DEPLOY.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.all): self.args.create_inventory = self.args.all self.args.install_cobbler = self.args.all self.args.download_os_images = self.args.all self.args.inv_add_ports_ipmi = self.args.all self.args.inv_add_ports_pxe = self.args.all self.args.reserve_ipmi_pxe_ips = self.args.all self.args.add_cobbler_distros = self.args.all self.args.add_cobbler_systems = self.args.all self.args.install_client_os = self.args.all if argparse_gen.is_arg_present(self.args.create_inventory): self._create_inventory() if argparse_gen.is_arg_present(self.args.install_cobbler): self._install_cobbler() if argparse_gen.is_arg_present(self.args.download_os_images): self._download_os_images() if argparse_gen.is_arg_present(self.args.inv_add_ports_ipmi): self._inv_add_ports_ipmi() if argparse_gen.is_arg_present(self.args.inv_add_ports_pxe): self._inv_add_ports_pxe() if argparse_gen.is_arg_present(self.args.reserve_ipmi_pxe_ips): self._reserve_ipmi_pxe_ips() if argparse_gen.is_arg_present(self.args.add_cobbler_distros): self._add_cobbler_distros() if argparse_gen.is_arg_present(self.args.add_cobbler_systems): self._add_cobbler_systems() if argparse_gen.is_arg_present(self.args.install_client_os): self._install_client_os() if argparse_gen.is_arg_present(self.args.all): print("\n\nPress enter to continue with node configuration ") print("and data switch setup, or 'T' to terminate ") print("POWER-Up. (To restart, type: 'pup post-deploy)") resp = input("\nEnter or 'T': ") if resp == 'T': sys.exit('POWER-Up stopped at user request') cmd = argparse_gen.Cmd.POST_DEPLOY.value if cmd == argparse_gen.Cmd.POST_DEPLOY.value: if gen.is_container(): print('Fail: Invalid subcommand in container', file=sys.stderr) sys.exit(1) if argparse_gen.is_arg_present(self.args.all): self.args.ssh_keyscan = self.args.all self.args.gather_mac_addr = self.args.all self.args.data_switches = self.args.all self.args.lookup_interface_names = self.args.all self.args.config_client_os = self.args.all if argparse_gen.is_arg_present(self.args.ssh_keyscan): self._ssh_keyscan() if argparse_gen.is_arg_present(self.args.gather_mac_addr): self._gather_mac_addr() if argparse_gen.is_arg_present(self.args.lookup_interface_names): self._lookup_interface_names() if argparse_gen.is_arg_present(self.args.config_client_os): self._config_client_os() if argparse_gen.is_arg_present(self.args.all): self._config_data_switches() if cmd == argparse_gen.Cmd.SOFTWARE.value: if not argparse_gen.is_arg_present(self.args.prep) and not \ argparse_gen.is_arg_present(self.args.init_clients) and not \ argparse_gen.is_arg_present(self.args.install) and not \ argparse_gen.is_arg_present(self.args.README) and not \ argparse_gen.is_arg_present(self.args.status): self.args.all = True if gen.GEN_SOFTWARE_PATH not in sys.path: sys.path.append(gen.GEN_SOFTWARE_PATH) try: self.args.name = self.args.name.split('.')[0] software_module = importlib.import_module(self.args.name) except ImportError as exc: print(exc) sys.exit(1) if 'software' not in dir(software_module): self.log.error( 'Software installation modules need to implement a ' 'class named "software"') sys.exit(1) else: soft = software_module.software(self.args.eval, self.args.non_interactive) if self.args.prep is True or self.args.all is True: try: soft.prep() except AttributeError as exc: print(exc.message) print('The software class needs to implement a ' 'method named "setup"') if self.args.init_clients is True or self.args.all is True: try: soft.init_clients() except AttributeError as exc: print(exc.message) print('The software class needs to implement a ' 'method named "init_clients"') if self.args.install is True or self.args.all is True: try: soft.install() except AttributeError as exc: print(exc.message) print('The software class needs to implement a ' 'method named "install"') if self.args.README is True: try: soft.README() except AttributeError as exc: print(exc.message) print('No "about" information available') if self.args.status is True: try: soft.status() except AttributeError as exc: print(exc.message) print('No "status" information available') if cmd == argparse_gen.Cmd.UTIL.value: if self.args.scan_pxe_network: self._scan_pxe_network() if self.args.scan_ipmi_network: self._scan_ipmi_network() if not cmd: print('Unrecognized POWER-Up command')