def set_mgmt_classes(self,mgmt_classes): """ Assigns a list of configuration management classes that can be assigned to any object, such as those used by Puppet's external_nodes feature. """ mgmt_classes_split = utils.input_string_or_list(mgmt_classes) self.mgmt_classes = utils.input_string_or_list(mgmt_classes_split) return True
def set_mgmt_classes(self, mgmt_classes): """ Assigns a list of configuration management classes that can be assigned to any object, such as those used by Puppet's external_nodes feature. """ mgmt_classes_split = utils.input_string_or_list(mgmt_classes) self.mgmt_classes = utils.input_string_or_list(mgmt_classes_split) return True
def filter_systems_or_profiles(self, selected_items, list_type): """ Return a list of valid profile or system objects selected from all profiles or systems by name, or everything if selected_items is empty """ if list_type == 'profile': all_objs = [profile for profile in self.api.profiles()] elif list_type == 'system': all_objs = [system for system in self.api.systems()] else: utils.die(self.logger, "Invalid list_type argument: " + list_type) all_objs.sort(self.sort_name) # no profiles/systems selection is made, let's process everything if not selected_items: return all_objs which_objs = [] selected_list = utils.input_string_or_list(selected_items) for obj in all_objs: if obj.name in selected_list: which_objs.append(obj) if not which_objs: utils.die(self.logger, "No valid systems or profiles were specified.") return which_objs
def __setattr__(self, name, value): if name in DEFAULTS: try: if DEFAULTS[name][1] == "str": value = str(value) elif DEFAULTS[name][1] == "int": value = int(value) elif DEFAULTS[name][1] == "bool": if utils.input_boolean(value): value = 1 else: value = 0 elif DEFAULTS[name][1] == "float": value = float(value) elif DEFAULTS[name][1] == "list": value = utils.input_string_or_list(value) elif DEFAULTS[name][1] == "dict": value = utils.input_string_or_hash(value)[1] except: raise AttributeError self.__dict__[name] = value if not utils.update_settings_file(self.to_datastruct()): raise AttributeError return 0 else: raise AttributeError
def set_name_servers(self,data): # FIXME: move to utils since shared with system if data == "<<inherit>>": data = [] data = utils.input_string_or_list(data) self.name_servers = data return True
def __setattr__(self,name,value): if DEFAULTS.has_key(name): try: if DEFAULTS[name][1] == "str": value = str(value) elif DEFAULTS[name][1] == "int": value = int(value) elif DEFAULTS[name][1] == "bool": if utils.input_boolean(value): value = 1 else: value = 0 elif DEFAULTS[name][1] == "float": value = float(value) elif DEFAULTS[name][1] == "list": value = utils.input_string_or_list(value) elif DEFAULTS[name][1] == "dict": value = utils.input_string_or_hash(value)[1] except: raise AttributeError, "failed to set %s to %s" % (name,str(value)) self.__dict__[name] = value if not utils.update_settings_file(self.to_datastruct()): raise AttributeError, "failed to save the settings file!" return 0 else: raise AttributeError, name
def set_name_servers(self, data): # FIXME: move to utils since shared with system if data == "<<inherit>>": data = [] data = utils.input_string_or_list(data) self.name_servers = data return True
def __setattr__(self, name, value): if name in DEFAULTS: try: if DEFAULTS[name][1] == "str": value = str(value) elif DEFAULTS[name][1] == "int": value = int(value) elif DEFAULTS[name][1] == "bool": if utils.input_boolean(value): value = 1 else: value = 0 elif DEFAULTS[name][1] == "float": value = float(value) elif DEFAULTS[name][1] == "list": value = utils.input_string_or_list(value) elif DEFAULTS[name][1] == "dict": value = utils.input_string_or_dict(value)[1] except: raise AttributeError self.__dict__[name] = value if not utils.update_settings_file(self.to_dict()): raise AttributeError return 0 else: raise AttributeError
def __setattr__(self, name, value): if DEFAULTS.has_key(name): try: if DEFAULTS[name][1] == "str": value = str(value) elif DEFAULTS[name][1] == "int": value = int(value) elif DEFAULTS[name][1] == "bool": if utils.input_boolean(value): value = 1 else: value = 0 elif DEFAULTS[name][1] == "float": value = float(value) elif DEFAULTS[name][1] == "list": value = utils.input_string_or_list(value) elif DEFAULTS[name][1] == "dict": value = utils.input_string_or_hash(value)[1] except: raise AttributeError, "failed to set %s to %s" % (name, str(value)) self.__dict__[name] = value utils.update_settings_file(name, value) return 0 else: raise AttributeError, name
def set_rpm_list(self, rpms): """ Rather than mirroring the entire contents of a repository (Fedora Extras, for instance, contains games, and we probably don't want those), make it possible to list the packages one wants out of those repos, so only those packages + deps can be mirrored. """ self.rpm_list = utils.input_string_or_list(rpms) return True
def set_rpm_list(self,rpms): """ Rather than mirroring the entire contents of a repository (Fedora Extras, for instance, contains games, and we probably don't want those), make it possible to list the packages one wants out of those repos, so only those packages + deps can be mirrored. """ self.rpm_list = utils.input_string_or_list(rpms,delim=" ") return True
def set_owners(self,data): """ The owners field is a comment unless using an authz module that pays attention to it, like authz_ownership, which ships with Cobbler but is off by default. Consult the Wiki docs for more info on CustomizableAuthorization. """ owners = utils.input_string_or_list(data) self.owners = owners return True
def set_owners(self, data): """ The owners field is a comment unless using an authz module that pays attention to it, like authz_ownership, which ships with Cobbler but is off by default. Consult the Wiki docs for more info on CustomizableAuthorization. """ owners = utils.input_string_or_list(data) self.owners = owners return True
def set_ipv6_secondaries(self,addresses,interface): intf = self.__get_interface(interface) data = utils.input_string_or_list(addresses) secondaries = [] for address in data: if address == "" or utils.is_ip(address): secondaries.append(address) else: raise CX(_("invalid format for IPv6 IP address (%s)") % address) intf["ipv6_secondaries"] = secondaries return True
def __find_compare(self, from_search, from_obj): if isinstance(from_obj, basestring): # FIXME: fnmatch is only used for string to string comparisions # which should cover most major usage, if not, this deserves fixing if fnmatch.fnmatch(from_obj.lower(), from_search.lower()): return True else: return False else: if isinstance(from_search, basestring): if isinstance(from_obj, list): from_search = utils.input_string_or_list(from_search) for x in from_search: if x not in from_obj: return False return True if isinstance(from_obj, dict): (junk, from_search) = utils.input_string_or_hash( from_search, allow_multiples=True) for x in from_search.keys(): y = from_search[x] if x not in from_obj: return False if not (y == from_obj[x]): # XXX return False return True if isinstance(from_obj, bool): if from_search.lower() in ["true", "1", "y", "yes"]: inp = True else: inp = False if inp == from_obj: return True return False raise CX(_("find cannot compare type: %s") % type(from_obj))
def __find_compare(self, from_search, from_obj): if isinstance(from_obj, basestring): # FIXME: fnmatch is only used for string to string comparisions # which should cover most major usage, if not, this deserves fixing if fnmatch.fnmatch(from_obj.lower(), from_search.lower()): return True else: return False else: if isinstance(from_search, basestring): if type(from_obj) == type([]): from_search = utils.input_string_or_list(from_search) for x in from_search: if x not in from_obj: return False return True if type(from_obj) == type({}): (junk, from_search) = utils.input_string_or_hash(from_search,allow_multiples=True) for x in from_search.keys(): y = from_search[x] if not from_obj.has_key(x): return False if not (y == from_obj[x]): return False return True if type(from_obj) == type(True): if from_search.lower() in [ "true", "1", "y", "yes" ]: inp = True else: inp = False if inp == from_obj: return True return False raise CX(_("find cannot compare type: %s") % type(from_obj))
def generate_netboot_iso(self, imagesdir, isolinuxdir, profiles=None, systems=None, exclude_dns=None): """ Create bootable CD image to be used for network installations """ # setup all profiles/systems lists all_profiles = [profile for profile in self.api.profiles()] all_profiles.sort(self.sort_name) all_systems = [system for system in self.api.systems()] all_systems.sort(self.sort_name) # convert input to lists which_profiles = utils.input_string_or_list(profiles) which_systems = utils.input_string_or_list(systems) # no profiles/systems selection is made, let's process everything do_all_systems = False do_all_profiles = False if len(which_profiles) == 0 and len(which_systems) == 0: do_all_systems = True do_all_profiles = True # setup isolinux.cfg isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") cfg = open(isolinuxcfg, "w+") cfg.write(self.iso_template) # iterate through selected profiles for profile in all_profiles: if profile.name in which_profiles or do_all_profiles is True: self.logger.info("processing profile: %s" % profile.name) dist = profile.get_conceptual_parent() distname = self.make_shorter(dist.name) self.copy_boot_files(dist, isolinuxdir, distname) cfg.write("\n") cfg.write("LABEL %s\n" % profile.name) cfg.write(" MENU LABEL %s\n" % profile.name) cfg.write(" kernel %s.krn\n" % distname) data = utils.blender(self.api, False, profile) if data["kickstart"].startswith("/"): data[ "kickstart"] = "http://%s:%s/cblr/svc/op/ks/profile/%s" % ( data["server"], self.api.settings().http_port, profile.name) append_line = " append initrd=%s.img" % distname if dist.breed == "suse": if data["proxy"] != "": append_line += " proxy=%s" % data["proxy"] if data["kernel_options"].has_key("install") and data[ "kernel_options"]["install"] != "": append_line += " install=%s" % data["kernel_options"][ "install"] del data["kernel_options"]["install"] else: append_line += " install=http://%s:%s/cblr/links/%s" % ( data["server"], self.api.settings().http_port, dist.name) if data["kernel_options"].has_key("autoyast") and data[ "kernel_options"]["autoyast"] != "": append_line += " autoyast=%s" % data["kernel_options"][ "autoyast"] del data["kernel_options"]["autoyast"] else: append_line += " autoyast=%s" % data["kickstart"] if dist.breed == "redhat": if data["proxy"] != "": append_line += " proxy=%s http_proxy=%s" % ( data["proxy"], data["proxy"]) append_line += " ks=%s" % data["kickstart"] if dist.breed in ["ubuntu", "debian"]: append_line += " auto-install/enable=true url=%s" % data[ "kickstart"] if data["proxy"] != "": append_line += " mirror/http/proxy=%s" % data["proxy"] append_line += self.add_remaining_kopts(data["kernel_options"]) cfg.write(append_line) length = len(append_line) if length > 254: self.logger.warning( "append line length is greater than 254 chars (%s chars)" % length) cfg.write("\nMENU SEPARATOR\n") # iterate through all selected systems for system in all_systems: if system.name in which_systems or do_all_systems is True: self.logger.info("processing system: %s" % system.name) profile = system.get_conceptual_parent() dist = profile.get_conceptual_parent() distname = self.make_shorter(dist.name) self.copy_boot_files(dist, isolinuxdir, distname) cfg.write("\n") cfg.write("LABEL %s\n" % system.name) cfg.write(" MENU LABEL %s\n" % system.name) cfg.write(" kernel %s.krn\n" % distname) data = utils.blender(self.api, False, system) if data["kickstart"].startswith("/"): data[ "kickstart"] = "http://%s:%s/cblr/svc/op/ks/system/%s" % ( data["server"], self.api.settings().http_port, system.name) append_line = " append initrd=%s.img" % distname if dist.breed == "suse": if data["proxy"] != "": append_line += " proxy=%s" % data["proxy"] if data["kernel_options"].has_key("install") and data[ "kernel_options"]["install"] != "": append_line += " install=%s" % data["kernel_options"][ "install"] del data["kernel_options"]["install"] else: append_line += " install=http://%s:%s/cblr/links/%s" % ( data["server"], self.api.settings().http_port, dist.name) if data["kernel_options"].has_key("autoyast") and data[ "kernel_options"]["autoyast"] != "": append_line += " autoyast=%s" % data["kernel_options"][ "autoyast"] del data["kernel_options"]["autoyast"] else: append_line += " autoyast=%s" % data["kickstart"] if dist.breed == "redhat": if data["proxy"] != "": append_line += " proxy=%s http_proxy=%s" % ( data["proxy"], data["proxy"]) append_line += " ks=%s" % data["kickstart"] if dist.breed in ["ubuntu", "debian"]: append_line += " auto-install/enable=true url=%s netcfg/disable_dhcp=true" % data[ "kickstart"] if data["proxy"] != "": append_line += " mirror/http/proxy=%s" % data["proxy"] # hostname is required as a parameter, the one in the preseed is not respected my_domain = "local.lan" if system.hostname != "": # if this is a FQDN, grab the first bit my_hostname = system.hostname.split(".")[0] _domain = system.hostname.split(".")[1:] if _domain: my_domain = ".".join(_domain) else: my_hostname = system.name.split(".")[0] _domain = system.name.split(".")[1:] if _domain: my_domain = ".".join(_domain) # at least for debian deployments configured for DHCP networking # this values are not used, but specifying here avoids questions append_line += " hostname=%s domain=%s" % (my_hostname, my_domain) # a similar issue exists with suite name, as installer requires # the existence of "stable" in the dists directory append_line += " suite=%s" % dist.os_version # try to add static ip boot options to avoid DHCP (interface/ip/netmask/gw/dns) # check for overrides first and clear them from kernel_options my_int = None my_ip = None my_mask = None my_gw = None my_dns = None if dist.breed in ["suse", "redhat"]: if data["kernel_options"].has_key("netmask") and data[ "kernel_options"]["netmask"] != "": my_mask = data["kernel_options"]["netmask"] del data["kernel_options"]["netmask"] if data["kernel_options"].has_key("gateway") and data[ "kernel_options"]["gateway"] != "": my_gw = data["kernel_options"]["gateway"] del data["kernel_options"]["gateway"] if dist.breed == "redhat": if data["kernel_options"].has_key("ksdevice") and data[ "kernel_options"]["ksdevice"] != "": my_int = data["kernel_options"]["ksdevice"] if my_int == "bootif": my_int = None del data["kernel_options"]["ksdevice"] if data["kernel_options"].has_key( "ip") and data["kernel_options"]["ip"] != "": my_ip = data["kernel_options"]["ip"] del data["kernel_options"]["ip"] if data["kernel_options"].has_key( "dns") and data["kernel_options"]["dns"] != "": my_dns = data["kernel_options"]["dns"] del data["kernel_options"]["dns"] if dist.breed == "suse": if data["kernel_options"].has_key("netdevice") and data[ "kernel_options"]["netdevice"] != "": my_int = data["kernel_options"]["netdevice"] del data["kernel_options"]["netdevice"] if data["kernel_options"].has_key("hostip") and data[ "kernel_options"]["hostip"] != "": my_ip = data["kernel_options"]["hostip"] del data["kernel_options"]["hostip"] if data["kernel_options"].has_key("nameserver") and data[ "kernel_options"]["nameserver"] != "": my_dns = data["kernel_options"]["nameserver"] del data["kernel_options"]["nameserver"] if dist.breed in ["ubuntu", "debian"]: if data["kernel_options"].has_key( "netcfg/choose_interface" ) and data["kernel_options"][ "netcfg/choose_interface"] != "": my_int = data["kernel_options"][ "netcfg/choose_interface"] del data["kernel_options"]["netcfg/choose_interface"] if data["kernel_options"].has_key( "netcfg/get_ipaddress" ) and data["kernel_options"]["netcfg/get_ipaddress"] != "": my_ip = data["kernel_options"]["netcfg/get_ipaddress"] del data["kernel_options"]["netcfg/get_ipaddress"] if data["kernel_options"].has_key( "netcfg/get_netmask" ) and data["kernel_options"]["netcfg/get_netmask"] != "": my_mask = data["kernel_options"]["netcfg/get_netmask"] del data["kernel_options"]["netcfg/get_netmask"] if data["kernel_options"].has_key( "netcfg/get_gateway" ) and data["kernel_options"]["netcfg/get_gateway"] != "": my_gw = data["kernel_options"]["netcfg/get_gateway"] del data["kernel_options"]["netcfg/get_gateway"] if data["kernel_options"].has_key( "netcfg/get_nameservers" ) and data["kernel_options"][ "netcfg/get_nameservers"] != "": my_dns = data["kernel_options"][ "netcfg/get_nameservers"] del data["kernel_options"]["netcfg/get_nameservers"] # if no kernel_options overrides are present find the management interface # do nothing when zero or multiple management interfaces are found if my_int is None: mgmt_ints = [] mgmt_ints_multi = [] slave_ints = [] if len(data["interfaces"].keys()) >= 1: for (iname, idata) in data["interfaces"].iteritems(): if idata["management"] == True and idata[ "interface_type"] in [ "master", "bond", "bridge" ]: # bonded/bridged management interface mgmt_ints_multi.append(iname) if idata["management"] == True and idata[ "interface_type"] not in [ "master", "bond", "bridge", "slave", "bond_slave", "bridge_slave", "bonded_bridge_slave" ]: # single management interface mgmt_ints.append(iname) if len(mgmt_ints_multi) == 1 and len(mgmt_ints) == 0: # bonded/bridged management interface, find a slave interface # if eth0 is a slave use that (it's what people expect) for (iname, idata) in data["interfaces"].iteritems(): if idata["interface_type"] in [ "slave", "bond_slave", "bridge_slave", "bonded_bridge_slave" ] and idata["interface_master"] == mgmt_ints_multi[ 0]: slave_ints.append(iname) if "eth0" in slave_ints: my_int = "eth0" else: my_int = slave_ints[0] # set my_ip from the bonded/bridged interface here my_ip = data["ip_address_" + data["interface_master_" + my_int]] my_mask = data["netmask_" + data["interface_master_" + my_int]] if len(mgmt_ints) == 1 and len(mgmt_ints_multi) == 0: # single management interface my_int = mgmt_ints[0] # lookup tcp/ip configuration data if my_ip is None and my_int is not None: if data.has_key("ip_address_" + my_int) and data["ip_address_" + my_int] != "": my_ip = data["ip_address_" + my_int] if my_mask is None and my_int is not None: if data.has_key("netmask_" + my_int) and data["netmask_" + my_int] != "": my_mask = data["netmask_" + my_int] if my_gw is None: if data.has_key("gateway") and data["gateway"] != "": my_gw = data["gateway"] if my_dns is None: if data.has_key( "name_servers") and data["name_servers"] != "": my_dns = data["name_servers"] # add information to the append_line if my_int is not None: if dist.breed == "suse": if data.has_key("mac_address_" + my_int) and data["mac_address_" + my_int] != "": append_line += " netdevice=%s" % data[ "mac_address_" + my_int].lower() else: append_line += " netdevice=%s" % my_int if dist.breed == "redhat": if data.has_key("mac_address_" + my_int) and data["mac_address_" + my_int] != "": append_line += " ksdevice=%s" % data["mac_address_" + my_int] else: append_line += " ksdevice=%s" % my_int if dist.breed in ["ubuntu", "debian"]: append_line += " netcfg/choose_interface=%s" % my_int if my_ip is not None: if dist.breed == "suse": append_line += " hostip=%s" % my_ip if dist.breed == "redhat": append_line += " ip=%s" % my_ip if dist.breed in ["ubuntu", "debian"]: append_line += " netcfg/get_ipaddress=%s" % my_ip if my_mask is not None: if dist.breed in ["suse", "redhat"]: append_line += " netmask=%s" % my_mask if dist.breed in ["ubuntu", "debian"]: append_line += " netcfg/get_netmask=%s" % my_mask if my_gw is not None: if dist.breed in ["suse", "redhat"]: append_line += " gateway=%s" % my_gw if dist.breed in ["ubuntu", "debian"]: append_line += " netcfg/get_gateway=%s" % my_gw if exclude_dns is None or my_dns is not None: if dist.breed == "suse": append_line += " nameserver=%s" % my_dns[0] if dist.breed == "redhat": if type(my_dns) == list: append_line += " dns=%s" % ",".join(my_dns) else: append_line += " dns=%s" % my_dns if dist.breed in ["ubuntu", "debian"]: append_line += " netcfg/get_nameservers=%s" % ",".join( my_dns) # add remaining kernel_options to append_line append_line += self.add_remaining_kopts(data["kernel_options"]) cfg.write(append_line) length = len(append_line) if length > 254: self.logger.warning( "append line length is greater than 254 chars (%s chars)" % length) cfg.write("\n") cfg.write("MENU END\n") cfg.close()
def set_cnames(self, cnames, interface): intf = self.__get_interface(interface) data = utils.input_string_or_list(cnames) intf["cnames"] = data return True
def generate_standalone_iso(self, imagesdir, isolinuxdir, distname, filesource, airgapped, profiles): """ Create bootable CD image to be used for handsoff CD installtions """ # Get the distro object for the requested distro # and then get all of its descendants (profiles/sub-profiles/systems) # with sort=True for profile/system heirarchy to allow menu indenting distro = self.api.find_distro(distname) if distro is None: utils.die(self.logger, "distro %s was not found, aborting" % distname) descendants = distro.get_descendants(sort=True) profiles = utils.input_string_or_list(profiles) if filesource is None: # Try to determine the source from the distro kernel path self.logger.debug("trying to locate source for distro") found_source = False (source_head, source_tail) = os.path.split(distro.kernel) while source_tail != '': if source_head == os.path.join(self.api.settings().webdir, "distro_mirror"): filesource = os.path.join(source_head, source_tail) found_source = True self.logger.debug("found source in %s" % filesource) break (source_head, source_tail) = os.path.split(source_head) # Can't find the source, raise an error if not found_source: utils.die( self.logger, "Error, no installation source found. When building a standalone ISO, you must specify a --source if the distro install tree is not hosted locally" ) self.logger.info("copying kernels and initrds for standalone distro") self.copy_boot_files(distro, isolinuxdir, None) self.logger.info("generating an isolinux.cfg") isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") cfg = open(isolinuxcfg, "w+") cfg.write(self.iso_template) if airgapped: repo_names_to_copy = {} for descendant in descendants: # if a list of profiles was given, skip any others and their systems if (profiles and ((descendant.COLLECTION_TYPE == 'profile' and descendant.name not in profiles) or (descendant.COLLECTION_TYPE == 'system' and descendant.profile not in profiles))): continue menu_indent = 0 if descendant.COLLECTION_TYPE == 'system': menu_indent = 4 data = utils.blender(self.api, False, descendant) cfg.write("\n") cfg.write("LABEL %s\n" % descendant.name) if menu_indent: cfg.write(" MENU INDENT %d\n" % menu_indent) cfg.write(" MENU LABEL %s\n" % descendant.name) cfg.write(" kernel %s\n" % os.path.basename(distro.kernel)) append_line = " append initrd=%s" % os.path.basename( distro.initrd) if distro.breed == "redhat": append_line += " ks=cdrom:/isolinux/%s.cfg" % descendant.name if distro.breed == "suse": append_line += " autoyast=file:///isolinux/%s.cfg install=cdrom:///" % descendant.name if "install" in data["kernel_options"]: del data["kernel_options"]["install"] if distro.breed in ["ubuntu", "debian"]: append_line += " auto-install/enable=true preseed/file=/cdrom/isolinux/%s.cfg" % descendant.name # add remaining kernel_options to append_line append_line += self.add_remaining_kopts(data["kernel_options"]) cfg.write(append_line) if descendant.COLLECTION_TYPE == 'profile': autoinstall_data = self.api.autoinstallgen.generate_autoinstall_for_profile( descendant.name) elif descendant.COLLECTION_TYPE == 'system': autoinstall_data = self.api.autoinstallgen.generate_autoinstall_for_system( descendant.name) if distro.breed == "redhat": cdregex = re.compile("^\s*url .*\n", re.IGNORECASE | re.MULTILINE) autoinstall_data = cdregex.sub("cdrom\n", autoinstall_data, count=1) if airgapped: descendant_repos = data['repos'] for repo_name in descendant_repos: repo_obj = self.api.find_repo(repo_name) error_fmt = (descendant.COLLECTION_TYPE + " " + descendant.name + " refers to repo " + repo_name + ", which %%s; cannot build airgapped ISO") if repo_obj is None: utils.die(self.logger, error_fmt % "does not exist") if not repo_obj.mirror_locally: utils.die( self.logger, error_fmt % "is not configured for local mirroring") # FIXME: don't hardcode mirrordir = os.path.join(self.settings.webdir, "repo_mirror", repo_obj.name) if not os.path.exists(mirrordir): utils.die( self.logger, error_fmt % "has a missing local mirror directory") repo_names_to_copy[repo_obj.name] = mirrordir # update the baseurl in autoinstall_data to use the cdrom copy of this repo reporegex = re.compile( "^(\s*repo --name=" + repo_obj.name + " --baseurl=).*", re.MULTILINE) autoinstall_data = reporegex.sub( r"\1" + "file:///mnt/source/repo_mirror/" + repo_obj.name, autoinstall_data) # rewrite any split-tree repos, such as in redhat, to use cdrom srcreporegex = re.compile( "^(\s*repo --name=\S+ --baseurl=).*/cobbler/ks_mirror/" + distro.name + "/?(.*)", re.MULTILINE) autoinstall_data = srcreporegex.sub( r"\1" + "file:///mnt/source" + r"\2", autoinstall_data) autoinstall_name = os.path.join(isolinuxdir, "%s.cfg" % descendant.name) autoinstall_file = open(autoinstall_name, "w+") autoinstall_file.write(autoinstall_data) autoinstall_file.close() self.logger.info("done writing config") cfg.write("\n") cfg.write("MENU END\n") cfg.close() if airgapped: # copy any repos found in profiles or systems to the iso build repodir = os.path.abspath( os.path.join(isolinuxdir, "..", "repo_mirror")) if not os.path.exists(repodir): os.makedirs(repodir) for repo_name in repo_names_to_copy: src = repo_names_to_copy[repo_name] dst = os.path.join(repodir, repo_name) self.logger.info(" - copying repo '" + repo_name + "' for airgapped ISO") ok = utils.rsync_files( src, dst, "--exclude=TRANS.TBL --exclude=cache/ --no-g", logger=self.logger, quiet=True) if not ok: utils.die(self.logger, "rsync of repo '" + repo_name + "' failed") # copy distro files last, since they take the most time cmd = "rsync -rlptgu --exclude=boot.cat --exclude=TRANS.TBL --exclude=isolinux/ %s/ %s/../" % ( filesource, isolinuxdir) self.logger.info("- copying distro %s files (%s)" % (distname, cmd)) rc = utils.subprocess_call(self.logger, cmd, shell=True) if rc: utils.die(self.logger, "rsync of distro files failed")
def generate_netboot_iso(self,imagesdir,isolinuxdir,profiles=None,systems=None,exclude_dns=None): """ Create bootable CD image to be used for network installations """ # setup all profiles/systems lists all_profiles = [profile for profile in self.api.profiles()] all_profiles.sort(self.sort_name) all_systems = [system for system in self.api.systems()] all_systems.sort(self.sort_name) # convert input to lists which_profiles = utils.input_string_or_list(profiles) which_systems = utils.input_string_or_list(systems) # no profiles/systems selection is made, let's process everything do_all_systems = False do_all_profiles = False if len(which_profiles) == 0 and len(which_systems) == 0: do_all_systems = True do_all_profiles = True # setup isolinux.cfg isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") cfg = open(isolinuxcfg, "w+") cfg.write(self.iso_template) # iterate through selected profiles for profile in all_profiles: if profile.name in which_profiles or do_all_profiles is True: self.logger.info("processing profile: %s" % profile.name) dist = profile.get_conceptual_parent() distname = self.make_shorter(dist.name) self.copy_boot_files(dist,isolinuxdir,distname) cfg.write("\n") cfg.write("LABEL %s\n" % profile.name) cfg.write(" MENU LABEL %s\n" % profile.name) cfg.write(" kernel %s.krn\n" % distname) data = utils.blender(self.api, False, profile) if data["kickstart"].startswith("/"): data["kickstart"] = "http://%s:%s/cblr/svc/op/ks/profile/%s" % ( data["server"], self.api.settings().http_port, profile.name ) append_line = " append initrd=%s.img" % distname if dist.breed == "suse": if data.has_key("proxy") and data["proxy"] != "": append_line += " proxy=%s" % data["proxy"] if data["kernel_options"].has_key("install") and data["kernel_options"]["install"] != "": append_line += " install=%s" % data["kernel_options"]["install"] del data["kernel_options"]["install"] else: append_line += " install=http://%s:%s/cblr/links/%s" % ( data["server"], self.api.settings().http_port, dist.name ) if data["kernel_options"].has_key("autoyast") and data["kernel_options"]["autoyast"] != "": append_line += " autoyast=%s" % data["kernel_options"]["autoyast"] del data["kernel_options"]["autoyast"] else: append_line += " autoyast=%s" % data["kickstart"] if dist.breed == "redhat": if data.has_key("proxy") and data["proxy"] != "": append_line += " proxy=%s http_proxy=%s" % (data["proxy"], data["proxy"]) append_line += " ks=%s" % data["kickstart"] if dist.breed in ["ubuntu","debian"]: append_line += " auto-install/enable=true url=%s" % data["kickstart"] if data.has_key("proxy") and data["proxy"] != "": append_line += " mirror/http/proxy=%s" % data["proxy"] append_line += self.add_remaining_kopts(data["kernel_options"]) cfg.write(append_line) cfg.write("\nMENU SEPARATOR\n") # iterate through all selected systems for system in all_systems: if system.name in which_systems or do_all_systems is True: self.logger.info("processing system: %s" % system.name) profile = system.get_conceptual_parent() dist = profile.get_conceptual_parent() distname = self.make_shorter(dist.name) self.copy_boot_files(dist,isolinuxdir,distname) cfg.write("\n") cfg.write("LABEL %s\n" % system.name) cfg.write(" MENU LABEL %s\n" % system.name) cfg.write(" kernel %s.krn\n" % distname) data = utils.blender(self.api, False, system) if data["kickstart"].startswith("/"): data["kickstart"] = "http://%s:%s/cblr/svc/op/ks/system/%s" % ( data["server"], self.api.settings().http_port, system.name ) append_line = " append initrd=%s.img" % distname if dist.breed == "suse": if data.has_key("proxy") and data["proxy"] != "": append_line += " proxy=%s" % data["proxy"] if data["kernel_options"].has_key("install") and data["kernel_options"]["install"] != "": append_line += " install=%s" % data["kernel_options"]["install"] del data["kernel_options"]["install"] else: append_line += " install=http://%s:%s/cblr/links/%s" % ( data["server"], self.api.settings().http_port, dist.name ) if data["kernel_options"].has_key("autoyast") and data["kernel_options"]["autoyast"] != "": append_line += " autoyast=%s" % data["kernel_options"]["autoyast"] del data["kernel_options"]["autoyast"] else: append_line += " autoyast=%s" % data["kickstart"] if dist.breed == "redhat": if data.has_key("proxy") and data["proxy"] != "": append_line += " proxy=%s http_proxy=%s" % (data["proxy"], data["proxy"]) append_line += " ks=%s" % data["kickstart"] if dist.breed in ["ubuntu","debian"]: append_line += " auto-install/enable=true url=%s netcfg/disable_dhcp=true" % data["kickstart"] if data.has_key("proxy") and data["proxy"] != "": append_line += " mirror/http/proxy=%s" % data["proxy"] # hostname is required as a parameter, the one in the preseed is not respected my_domain = "local.lan" if system.hostname != "": # if this is a FQDN, grab the first bit my_hostname = system.hostname.split(".")[0] _domain = system.hostname.split(".")[1:] if _domain: my_domain = ".".join(_domain) else: my_hostname = system.name.split(".")[0] _domain = system.name.split(".")[1:] if _domain: my_domain = ".".join(_domain) # at least for debian deployments configured for DHCP networking # this values are not used, but specifying here avoids questions append_line += " hostname=%s domain=%s" % (my_hostname, my_domain) # a similar issue exists with suite name, as installer requires # the existence of "stable" in the dists directory append_line += " suite=%s" % dist.os_version # try to add static ip boot options to avoid DHCP (interface/ip/netmask/gw/dns) # check for overrides first and clear them from kernel_options my_int = None; my_ip = None; my_mask = None; my_gw = None; my_dns = None if dist.breed in ["suse", "redhat"]: if data["kernel_options"].has_key("netmask") and data["kernel_options"]["netmask"] != "": my_mask = data["kernel_options"]["netmask"] del data["kernel_options"]["netmask"] if data["kernel_options"].has_key("gateway") and data["kernel_options"]["gateway"] != "": my_gw = data["kernel_options"]["gateway"] del data["kernel_options"]["gateway"] if dist.breed == "redhat": if data["kernel_options"].has_key("ksdevice") and data["kernel_options"]["ksdevice"] != "": my_int = data["kernel_options"]["ksdevice"] if my_int == "bootif": my_int = None del data["kernel_options"]["ksdevice"] if data["kernel_options"].has_key("ip") and data["kernel_options"]["ip"] != "": my_ip = data["kernel_options"]["ip"] del data["kernel_options"]["ip"] if data["kernel_options"].has_key("dns") and data["kernel_options"]["dns"] != "": my_dns = data["kernel_options"]["dns"] del data["kernel_options"]["dns"] if dist.breed == "suse": if data["kernel_options"].has_key("netdevice") and data["kernel_options"]["netdevice"] != "": my_int = data["kernel_options"]["netdevice"] del data["kernel_options"]["netdevice"] if data["kernel_options"].has_key("hostip") and data["kernel_options"]["hostip"] != "": my_ip = data["kernel_options"]["hostip"] del data["kernel_options"]["hostip"] if data["kernel_options"].has_key("nameserver") and data["kernel_options"]["nameserver"] != "": my_dns = data["kernel_options"]["nameserver"] del data["kernel_options"]["nameserver"] if dist.breed in ["ubuntu","debian"]: if data["kernel_options"].has_key("netcfg/choose_interface") and data["kernel_options"]["netcfg/choose_interface"] != "": my_int = data["kernel_options"]["netcfg/choose_interface"] del data["kernel_options"]["netcfg/choose_interface"] if data["kernel_options"].has_key("netcfg/get_ipaddress") and data["kernel_options"]["netcfg/get_ipaddress"] != "": my_ip = data["kernel_options"]["netcfg/get_ipaddress"] del data["kernel_options"]["netcfg/get_ipaddress"] if data["kernel_options"].has_key("netcfg/get_netmask") and data["kernel_options"]["netcfg/get_netmask"] != "": my_mask = data["kernel_options"]["netcfg/get_netmask"] del data["kernel_options"]["netcfg/get_netmask"] if data["kernel_options"].has_key("netcfg/get_gateway") and data["kernel_options"]["netcfg/get_gateway"] != "": my_gw = data["kernel_options"]["netcfg/get_gateway"] del data["kernel_options"]["netcfg/get_gateway"] if data["kernel_options"].has_key("netcfg/get_nameservers") and data["kernel_options"]["netcfg/get_nameservers"] != "": my_dns = data["kernel_options"]["netcfg/get_nameservers"] del data["kernel_options"]["netcfg/get_nameservers"] # if no kernel_options overrides are present find the management interface # do nothing when zero or multiple management interfaces are found if my_int is None: mgmt_ints = []; mgmt_ints_multi = []; slave_ints = [] if len(data["interfaces"].keys()) >= 1: for (iname, idata) in data["interfaces"].iteritems(): if idata["management"] == True and idata["interface_type"] in ["master","bond","bridge"]: # bonded/bridged management interface mgmt_ints_multi.append(iname) if idata["management"] == True and idata["interface_type"] not in ["master","bond","bridge","slave","bond_slave","bridge_slave","bonded_bridge_slave"]: # single management interface mgmt_ints.append(iname) if len(mgmt_ints_multi) == 1 and len(mgmt_ints) == 0: # bonded/bridged management interface, find a slave interface # if eth0 is a slave use that (it's what people expect) for (iname, idata) in data["interfaces"].iteritems(): if idata["interface_type"] in ["slave","bond_slave","bridge_slave","bonded_bridge_slave"] and idata["interface_master"] == mgmt_ints_multi[0]: slave_ints.append(iname) if "eth0" in slave_ints: my_int = "eth0" else: my_int = slave_ints[0] # set my_ip from the bonded/bridged interface here my_ip = data["ip_address_" + data["interface_master_" + my_int]] my_mask = data["netmask_" + data["interface_master_" + my_int]] if len(mgmt_ints) == 1 and len(mgmt_ints_multi) == 0: # single management interface my_int = mgmt_ints[0] # lookup tcp/ip configuration data if my_ip is None and my_int is not None: if data.has_key("ip_address_" + my_int) and data["ip_address_" + my_int] != "": my_ip = data["ip_address_" + my_int] if my_mask is None and my_int is not None: if data.has_key("netmask_" + my_int) and data["netmask_" + my_int] != "": my_mask = data["netmask_" + my_int] if my_gw is None: if data.has_key("gateway") and data["gateway"] != "": my_gw = data["gateway"] if my_dns is None: if data.has_key("name_servers") and data["name_servers"] != "": my_dns = data["name_servers"] # add information to the append_line if my_int is not None: if dist.breed == "suse": if data.has_key("mac_address_" + my_int) and data["mac_address_" + my_int] != "": append_line += " netdevice=%s" % data["mac_address_" + my_int].lower() else: append_line += " netdevice=%s" % my_int if dist.breed == "redhat": if data.has_key("mac_address_" + my_int) and data["mac_address_" + my_int] != "": append_line += " ksdevice=%s" % data["mac_address_" + my_int] else: append_line += " ksdevice=%s" % my_int if dist.breed in ["ubuntu","debian"]: append_line += " netcfg/choose_interface=%s" % my_int if my_ip is not None: if dist.breed == "suse": append_line += " hostip=%s" % my_ip if dist.breed == "redhat": append_line += " ip=%s" % my_ip if dist.breed in ["ubuntu","debian"]: append_line += " netcfg/get_ipaddress=%s" % my_ip if my_mask is not None: if dist.breed in ["suse","redhat"]: append_line += " netmask=%s" % my_mask if dist.breed in ["ubuntu","debian"]: append_line += " netcfg/get_netmask=%s" % my_mask if my_gw is not None: if dist.breed in ["suse","redhat"]: append_line += " gateway=%s" % my_gw if dist.breed in ["ubuntu","debian"]: append_line += " netcfg/get_gateway=%s" % my_gw if exclude_dns is None or my_dns is not None: if dist.breed == "suse": append_line += " nameserver=%s" % my_dns[0] if dist.breed == "redhat": if type(my_dns) == list: append_line += " dns=%s" % ",".join(my_dns) else: append_line += " dns=%s" % my_dns if dist.breed in ["ubuntu","debian"]: append_line += " netcfg/get_nameservers=%s" % ",".join(my_dns) # add remaining kernel_options to append_line append_line += self.add_remaining_kopts(data["kernel_options"]) cfg.write(append_line) cfg.write("\n") cfg.write("MENU END\n") cfg.close()
def set_name_servers(self, data): data = utils.input_string_or_list(data) self.name_servers = data return True
def set_apt_dists(self, value): self.apt_dists = utils.input_string_or_list(value) return True
def set_packages(self, packages): self.packages = utils.input_string_or_list(packages) return True
def set_files(self, files): self.files = utils.input_string_or_list(files) return True
def set_cnames(self,cnames,interface): intf = self.__get_interface(interface) data = utils.input_string_or_list(cnames) intf["cnames"] = data return True
def set_name_servers_search(self, data): if data == "<<inherit>>": data = [] data = utils.input_string_or_list(data) self.name_servers_search = data return True
def set_ipv6_static_routes(self, routes, interface): intf = self.__get_interface(interface) data = utils.input_string_or_list(routes) intf["ipv6_static_routes"] = data return True
def set_name_servers_search(self,data): if data == "<<inherit>>": data = [] data = utils.input_string_or_list(data) self.name_servers_search = data return True
def generate_standalone_iso(self, imagesdir, isolinuxdir, distname, filesource, airgapped, profiles): """ Create bootable CD image to be used for handsoff CD installtions """ # Get the distro object for the requested distro # and then get all of its descendants (profiles/sub-profiles/systems) # with sort=True for profile/system heirarchy to allow menu indenting distro = self.api.find_distro(distname) if distro is None: utils.die(self.logger, "distro %s was not found, aborting" % distname) descendants = distro.get_descendants(sort=True) profiles = utils.input_string_or_list(profiles) if filesource is None: # Try to determine the source from the distro kernel path self.logger.debug("trying to locate source for distro") found_source = False (source_head, source_tail) = os.path.split(distro.kernel) while source_tail != '': if source_head == os.path.join(self.api.settings().webdir, "distro_mirror"): filesource = os.path.join(source_head, source_tail) found_source = True self.logger.debug("found source in %s" % filesource) break (source_head, source_tail) = os.path.split(source_head) # Can't find the source, raise an error if not found_source: utils.die(self.logger, "Error, no installation source found. When building a standalone ISO, you must specify a --source if the distro install tree is not hosted locally") self.logger.info("copying kernels and initrds for standalone distro") self.copy_boot_files(distro, isolinuxdir, None) self.logger.info("generating an isolinux.cfg") isolinuxcfg = os.path.join(isolinuxdir, "isolinux.cfg") cfg = open(isolinuxcfg, "w+") cfg.write(self.iso_template) if airgapped: repo_names_to_copy = {} for descendant in descendants: # if a list of profiles was given, skip any others and their systems if (profiles and ((descendant.COLLECTION_TYPE == 'profile' and descendant.name not in profiles) or (descendant.COLLECTION_TYPE == 'system' and descendant.profile not in profiles))): continue menu_indent = 0 if descendant.COLLECTION_TYPE == 'system': menu_indent = 4 data = utils.blender(self.api, False, descendant) cfg.write("\n") cfg.write("LABEL %s\n" % descendant.name) if menu_indent: cfg.write(" MENU INDENT %d\n" % menu_indent) cfg.write(" MENU LABEL %s\n" % descendant.name) cfg.write(" kernel %s\n" % os.path.basename(distro.kernel)) append_line = " append initrd=%s" % os.path.basename(distro.initrd) if distro.breed == "redhat": append_line += " ks=cdrom:/isolinux/%s.cfg" % descendant.name if distro.breed == "suse": append_line += " autoyast=file:///isolinux/%s.cfg install=cdrom:///" % descendant.name if "install" in data["kernel_options"]: del data["kernel_options"]["install"] if distro.breed in ["ubuntu", "debian"]: append_line += " auto-install/enable=true preseed/file=/cdrom/isolinux/%s.cfg" % descendant.name # add remaining kernel_options to append_line append_line += self.add_remaining_kopts(data["kernel_options"]) cfg.write(append_line) if descendant.COLLECTION_TYPE == 'profile': autoinstall_data = self.api.autoinstallgen.generate_autoinstall_for_profile(descendant.name) elif descendant.COLLECTION_TYPE == 'system': autoinstall_data = self.api.autoinstallgen.generate_autoinstall_for_system(descendant.name) if distro.breed == "redhat": cdregex = re.compile("^\s*url .*\n", re.IGNORECASE | re.MULTILINE) autoinstall_data = cdregex.sub("cdrom\n", autoinstall_data, count=1) if airgapped: descendant_repos = data['repos'] for repo_name in descendant_repos: repo_obj = self.api.find_repo(repo_name) error_fmt = (descendant.COLLECTION_TYPE + " " + descendant.name + " refers to repo " + repo_name + ", which %%s; cannot build airgapped ISO") if repo_obj is None: utils.die(self.logger, error_fmt % "does not exist") if not repo_obj.mirror_locally: utils.die(self.logger, error_fmt % "is not configured for local mirroring") # FIXME: don't hardcode mirrordir = os.path.join(self.settings.webdir, "repo_mirror", repo_obj.name) if not os.path.exists(mirrordir): utils.die(self.logger, error_fmt % "has a missing local mirror directory") repo_names_to_copy[repo_obj.name] = mirrordir # update the baseurl in autoinstall_data to use the cdrom copy of this repo reporegex = re.compile("^(\s*repo --name=" + repo_obj.name + " --baseurl=).*", re.MULTILINE) autoinstall_data = reporegex.sub(r"\1" + "file:///mnt/source/repo_mirror/" + repo_obj.name, autoinstall_data) # rewrite any split-tree repos, such as in redhat, to use cdrom srcreporegex = re.compile("^(\s*repo --name=\S+ --baseurl=).*/cobbler/ks_mirror/" + distro.name + "/?(.*)", re.MULTILINE) autoinstall_data = srcreporegex.sub(r"\1" + "file:///mnt/source" + r"\2", autoinstall_data) autoinstall_name = os.path.join(isolinuxdir, "%s.cfg" % descendant.name) autoinstall_file = open(autoinstall_name, "w+") autoinstall_file.write(autoinstall_data) autoinstall_file.close() self.logger.info("done writing config") cfg.write("\n") cfg.write("MENU END\n") cfg.close() if airgapped: # copy any repos found in profiles or systems to the iso build repodir = os.path.abspath(os.path.join(isolinuxdir, "..", "repo_mirror")) if not os.path.exists(repodir): os.makedirs(repodir) for repo_name in repo_names_to_copy: src = repo_names_to_copy[repo_name] dst = os.path.join(repodir, repo_name) self.logger.info(" - copying repo '" + repo_name + "' for airgapped ISO") ok = utils.rsync_files(src, dst, "--exclude=TRANS.TBL --exclude=cache/ --no-g", logger=self.logger, quiet=True) if not ok: utils.die(self.logger, "rsync of repo '" + repo_name + "' failed") # copy distro files last, since they take the most time cmd = "rsync -rlptgu --exclude=boot.cat --exclude=TRANS.TBL --exclude=isolinux/ %s/ %s/../" % (filesource, isolinuxdir) self.logger.info("- copying distro %s files (%s)" % (distname, cmd)) rc = utils.subprocess_call(self.logger, cmd, shell=True) if rc: utils.die(self.logger, "rsync of distro files failed")
def set_ipv6_static_routes(self,routes,interface): intf = self.__get_interface(interface) data = utils.input_string_or_list(routes) intf["ipv6_static_routes"] = data return True
def set_name_servers(self,data): if data == "<<inherit>>": data = [] data = utils.input_string_or_list(data, delim=" ") self.name_servers = data return True