def do_auto(self, subcmd, opts, *args): """${cmd_name}: auto detect image type from magic header Usage: ${name} ${cmd_name} <ksfile> ${cmd_option_list} """ def parse_magic_line(re_str, pstr, ptype='mic'): ptn = re.compile(re_str) m = ptn.match(pstr) if not m or not m.groups(): return None inline_argv = m.group(1).strip() if ptype == 'mic': m2 = re.search('(?P<format>\w+)', inline_argv) elif ptype == 'mic2': m2 = re.search('(-f|--format(=)?)\s*(?P<format>\w+)', inline_argv) else: return None if m2: cmdname = m2.group('format') inline_argv = inline_argv.replace(m2.group(0), '') return (cmdname, inline_argv) return None if not args: self.do_help(['help', subcmd]) return None if len(args) != 1: raise errors.Usage("Extra arguments given") if not os.path.exists(args[0]): raise errors.CreatorError("Can't find the file: %s" % args[0]) with open(args[0], 'r') as rf: first_line = rf.readline() mic_re = '^#\s*-\*-mic-options-\*-\s+(.*)\s+-\*-mic-options-\*-' mic2_re = '^#\s*-\*-mic2-options-\*-\s+(.*)\s+-\*-mic2-options-\*-' result = parse_magic_line(mic_re, first_line, 'mic') \ or parse_magic_line(mic2_re, first_line, 'mic2') if not result: raise errors.KsError("Invalid magic line in file: %s" % args[0]) if result[0] not in self._subcmds: raise errors.KsError("Unsupport format '%s' in %s" % (result[0], args[0])) argv = ' '.join(result + args).split() self.main(argv)
def addUser(self, userconfig): args = [ "/usr/sbin/useradd" ] if userconfig.groups: args += [ "--groups", string.join(userconfig.groups, ",") ] if userconfig.name: args.append(userconfig.name) try: dev_null = os.open("/dev/null", os.O_WRONLY) subprocess.call(args, stdout = dev_null, stderr = dev_null, preexec_fn = self.chroot) os.close(dev_null) except: msger.warning('Cannot add user using "useradd"') if userconfig.password not in (None, ""): if userconfig.isCrypted: self.set_encrypted_passwd(userconfig.name, userconfig.password) else: self.set_unencrypted_passwd(userconfig.name, userconfig.password) else: self.set_empty_passwd(userconfig.name) else: raise errors.KsError("Invalid kickstart command: %s" \ % userconfig.__str__())
def read_kickstart(path): """Parse a kickstart file and return a KickstartParser instance. This is a simple utility function which takes a path to a kickstart file, parses it and returns a pykickstart KickstartParser instance which can be then passed to an ImageCreator constructor. If an error occurs, a CreatorError exception is thrown. """ #version = ksversion.makeVersion() #ks = ksparser.KickstartParser(version) using_version = ksversion.DEVEL commandMap[using_version]["desktop"] = desktop.Moblin_Desktop commandMap[using_version]["repo"] = moblinrepo.Moblin_Repo commandMap[using_version]["bootloader"] = micboot.Moblin_Bootloader dataMap[using_version]["RepoData"] = moblinrepo.Moblin_RepoData superclass = ksversion.returnClassForVersion(version=using_version) class KSHandlers(superclass): def __init__(self, mapping={}): superclass.__init__(self, mapping=commandMap[using_version]) ks = ksparser.KickstartParser(KSHandlers()) try: ks.readKickstart(path) except kserrors.KickstartError, e: raise errors.KsError("'%s': %s" % (path, str(e)))
def apply(self, kstimezone): self._check_sysconfig() tz = kstimezone.timezone or "America/New_York" utc = str(kstimezone.isUtc) f = open(self.path("/etc/sysconfig/clock"), "w+") f.write("ZONE=\"" + tz + "\"\n") f.write("UTC=" + utc + "\n") f.close() if not os.path.exists("/opt/etc"): fs.makedirs("/opt/etc") tz_source = "/usr/share/zoneinfo/%s" % (tz) tz_midst = "/opt/etc/localtime" tz_dest = "/etc/localtime" try: lncmd = fs.find_binary_inchroot('ln', self.instroot) if lncmd: self.call([lncmd, "-s", tz_source, tz_midst]) self.call([lncmd, "-s", tz_midst, tz_dest]) else: lncmd = fs.find_binary_path('ln') subprocess.call( [lncmd, "-s", self.path(tz_source), self.path(tz_midst)]) subprocess.call( [lncmd, "-s", self.path(tz_midst), self.path(tz_dest)]) except (IOError, OSError), (errno, msg): raise errors.KsError("Timezone setting error: %s" % msg)
def read_kickstart(path): """Parse a kickstart file and return a KickstartParser instance. This is a simple utility function which takes a path to a kickstart file, parses it and returns a pykickstart KickstartParser instance which can be then passed to an ImageCreator constructor. If an error occurs, a CreatorError exception is thrown. """ #version = ksversion.makeVersion() #ks = ksparser.KickstartParser(version) using_version = ksversion.DEVEL commandMap[using_version]["desktop"] = desktop.Moblin_Desktop commandMap[using_version]["repo"] = moblinrepo.Moblin_Repo commandMap[using_version]["bootloader"] = micboot.Moblin_Bootloader commandMap[using_version]["part"] = partition.MeeGo_Partition commandMap[using_version]["partition"] = partition.MeeGo_Partition commandMap[using_version]["btrfs"] = btrfs.BTRFS dataMap[using_version]["RepoData"] = moblinrepo.Moblin_RepoData dataMap[using_version]["PartData"] = partition.MeeGo_PartData dataMap[using_version]["BTRFSData"] = btrfs.BTRFSData superclass = ksversion.returnClassForVersion(version=using_version) class KSHandlers(superclass): def __init__(self, mapping={}): superclass.__init__(self, mapping=commandMap[using_version]) self.prepackages = PrePackages() self.attachment = Attachment() def __str__(self): retval = superclass.__str__(self) if self.prepackages: retval += self.prepackages.__str__() if self.attachment: retval += self.attachment.__str__() return retval ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False) ks.registerSection(PackScriptSection(ks.handler, dataObj=PackScript)) ks.registerSection(PrepackageSection(ks.handler)) ks.registerSection(AttachmentSection(ks.handler)) try: ks.readKickstart(path) except (kserrors.KickstartParseError, kserrors.KickstartError) as err: if msger.ask("Errors occured on kickstart file, skip and continue?"): msger.warning("%s" % err) pass else: raise errors.KsError("%s" % err) return ks
def do_auto(parser, ksfile, argv): """${cmd_name}: auto detect image type from magic header Usage: ${name} ${cmd_name} <ksfile> ${cmd_option_list} """ def parse_magic_line(re_str, pstr, ptype='mic'): ptn = re.compile(re_str) m = ptn.match(pstr) if not m or not m.groups(): return None inline_argv = m.group(1).strip() if ptype == 'mic': m2 = re.search('(?P<format>\w+)', inline_argv) elif ptype == 'mic2': m2 = re.search('(-f|--format(=)?)\s*(?P<format>\w+)', inline_argv) else: return None if m2: cmdname = m2.group('format') inline_argv = inline_argv.replace(m2.group(0), '') return (cmdname, inline_argv) return None if not os.path.exists(ksfile): raise errors.CreatorError("Can't find the file: %s" % ksfile) with open(ksfile, 'r') as rf: first_line = rf.readline() mic_re = '^#\s*-\*-mic-options-\*-\s+(.*)\s+-\*-mic-options-\*-' mic2_re = '^#\s*-\*-mic2-options-\*-\s+(.*)\s+-\*-mic2-options-\*-' result = parse_magic_line(mic_re, first_line, 'mic') \ or parse_magic_line(mic2_re, first_line, 'mic2') if not result: raise errors.KsError("Invalid magic line in file: %s" % ksfile) ksargv = ' '.join(result).split() argv.remove("auto") index = argv.index("create") #insert the subcommand argv.insert(index + 1, ksargv[0]) options = argv + ksargv[1:] args = parser.parse_args(options) main(parser, args, options)
def apply(self, ksnet): fs.makedirs(self.path("/etc/sysconfig/network-scripts")) useipv6 = False nodns = False hostname = None gateway = None nameservers = None for network in ksnet.network: if not network.device: raise errors.KsError("No --device specified with " "network kickstart command") if (network.onboot and network.bootProto.lower() != "dhcp" and not (network.ip and network.netmask)): raise errors.KsError("No IP address and/or netmask " "specified with static " "configuration for '%s'" % network.device) self.write_ifcfg(network) self.write_wepkey(network) if network.ipv6: useipv6 = True if network.nodns: nodns = True if network.hostname: hostname = network.hostname if network.gateway: gateway = network.gateway if network.nameserver: nameservers = network.nameserver.split(",") self.write_sysconfig(useipv6, hostname, gateway) self.write_hosts(hostname) self.write_resolv(nodns, nameservers)
def _parse_kickstart(self, ksconf=None): if not ksconf: return ksconf = misc.normalize_ksfile(ksconf, self.create['release'], self.create['arch']) ks = kickstart.read_kickstart(ksconf) self.create['ks'] = ks self.create['name'] = os.path.splitext(os.path.basename(ksconf))[0] self.create['name'] = misc.build_name(ksconf, self.create['release'], self.create['name_prefix'], self.create['name_suffix']) msger.info("Retrieving repo metadata:") ksrepos = misc.get_repostrs_from_ks(ks) if not ksrepos: raise errors.KsError('no valid repos found in ks file') for repo in ksrepos: if 'baseurl' in repo and repo['baseurl'].startswith("file:"): repourl = repo['baseurl'].replace('file:', '') repourl = "/%s" % repourl.lstrip('/') self.create['localrepos'].append(repourl) self.create['repomd'] = misc.get_metadata_from_repos( ksrepos, self.create['cachedir']) msger.raw(" DONE") target_archlist, archlist = misc.get_arch(self.create['repomd']) if self.create['arch']: if self.create['arch'] not in archlist: raise errors.ConfigError("Invalid arch %s for repository. " "Valid arches: %s" \ % (self.create['arch'], ', '.join(archlist))) else: if len(target_archlist) == 1: self.create['arch'] = str(target_archlist[0]) msger.info("\nUse detected arch %s." % target_archlist[0]) else: raise errors.ConfigError("Please specify a valid arch, " "the choice can be: %s" \ % ', '.join(archlist)) kickstart.resolve_groups(self.create, self.create['repomd']) # check selinux, it will block arm and btrfs image creation misc.selinux_check(self.create['arch'], [p.fstype for p in ks.handler.partition.partitions])
def set_unencrypted_passwd(self, user, password): for p in ("/bin/echo", "/usr/sbin/chpasswd"): if not os.path.exists("%s/%s" %(self.instroot, p)): raise errors.KsError("Unable to set unencrypted password due " "to lack of %s" % p) p1 = subprocess.Popen(["/bin/echo", "%s:%s" %(user, password)], stdout = subprocess.PIPE, preexec_fn = self.chroot) p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"], stdin = p1.stdout, stdout = subprocess.PIPE, preexec_fn = self.chroot) p2.communicate()
def read_kickstart(path): """Parse a kickstart file and return a KickstartParser instance. This is a simple utility function which takes a path to a kickstart file, parses it and returns a pykickstart KickstartParser instance which can be then passed to an ImageCreator constructor. If an error occurs, a CreatorError exception is thrown. """ #version = ksversion.makeVersion() #ks = ksparser.KickstartParser(version) using_version = ksversion.DEVEL commandMap[using_version]["desktop"] = desktop.Mic_Desktop commandMap[using_version]["repo"] = micrepo.Mic_Repo commandMap[using_version]["tpk_repo"] = micrepo.Mic_Tpk_Repo commandMap[using_version]["bootloader"] = micboot.Mic_Bootloader commandMap[using_version]["part"] = partition.Mic_Partition commandMap[using_version]["partition"] = partition.Mic_Partition commandMap[using_version][ "installerfw_plugins"] = installerfw.Mic_installerfw dataMap[using_version]["RepoData"] = micrepo.Mic_RepoData dataMap[using_version]["Tpk_RepoData"] = micrepo.Mic_Tpk_RepoData dataMap[using_version]["PartData"] = partition.Mic_PartData superclass = ksversion.returnClassForVersion(version=using_version) class KSHandlers(superclass): def __init__(self): superclass.__init__(self, mapping=commandMap[using_version]) self.prepackages = ksparser.Packages() self.attachment = ksparser.Packages() ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False) ks.registerSection(PrepackageSection(ks.handler)) ks.registerSection(AttachmentSection(ks.handler)) try: ks.readKickstart(path) except (kserrors.KickstartParseError, kserrors.KickstartError), err: if msger.ask("Errors occured on kickstart file, skip and continue?"): msger.warning("%s" % err) pass else: raise errors.KsError("%s" % err)
def apply(self, kstimezone): self._check_sysconfig() tz = kstimezone.timezone or "America/New_York" utc = str(kstimezone.isUtc) f = open(self.path("/etc/sysconfig/clock"), "w+") f.write("ZONE=\"" + tz + "\"\n") f.write("UTC=" + utc + "\n") f.close() tz_source = "/usr/share/zoneinfo/%s" % (tz) tz_dest = "/etc/localtime" try: cpcmd = fs.find_binary_inchroot('cp', self.instroot) if cpcmd: self.call([cpcmd, "-f", tz_source, tz_dest]) else: cpcmd = fs.find_binary_path('cp') subprocess.call([cpcmd, "-f", self.path(tz_source), self.path(tz_dest)]) except (IOError, OSError) as xxx_todo_changeme: (errno, msg) = xxx_todo_changeme.args raise errors.KsError("Timezone setting error: %s" % msg)
def read_kickstart(path): """Parse a kickstart file and return a KickstartParser instance. This is a simple utility function which takes a path to a kickstart file, parses it and returns a pykickstart KickstartParser instance which can be then passed to an ImageCreator constructor. If an error occurs, a CreatorError exception is thrown. """ #version = ksversion.makeVersion() #ks = ksparser.KickstartParser(version) using_version = ksversion.DEVEL commandMap[using_version]["desktop"] = desktop.Moblin_Desktop commandMap[using_version]["repo"] = moblinrepo.Moblin_Repo commandMap[using_version]["bootloader"] = micboot.Moblin_Bootloader dataMap[using_version]["RepoData"] = moblinrepo.Moblin_RepoData superclass = ksversion.returnClassForVersion(version=using_version) class KSHandlers(superclass): def __init__(self, mapping={}): superclass.__init__(self, mapping=commandMap[using_version]) ks = ksparser.KickstartParser(KSHandlers()) try: ks.readKickstart(path) except kserrors.KickstartParseError, e: msgptn = re.compile("^\D*(\d+).*(Section does not end with.*)$", re.S) m = msgptn.match(str(e)) if m: lineno = m.group(1) wrnmsg = m.group(2) msger.warning("'%s:%s': %s" % (path, lineno, wrnmsg)) else: raise errors.KsError("'%s': %s" % (path, str(e)))
def __set_ksconf(self, ksconf): if not os.path.isfile(ksconf): raise errors.KsError('Cannot find ks file: %s' % ksconf) self.__ksconf = ksconf self._parse_kickstart(ksconf)
def call(self, args): if not os.path.exists("%s/%s" %(self.instroot, args[0])): raise errors.KsError("Can't find %s in chroot" % args[0]) subprocess.call(args, preexec_fn = self.chroot)
commandMap[using_version]["bootloader"] = micboot.Moblin_Bootloader dataMap[using_version]["RepoData"] = moblinrepo.Moblin_RepoData superclass = ksversion.returnClassForVersion(version=using_version) class KSHandlers(superclass): def __init__(self, mapping={}): superclass.__init__(self, mapping=commandMap[using_version]) ks = ksparser.KickstartParser(KSHandlers()) try: ks.readKickstart(path) except kserrors.KickstartError, e: raise errors.KsError("'%s': %s" % (path, str(e))) except kserrors.KickstartParseError, e: raise errors.KsError("'%s': %s" % (path, str(e))) return ks def build_name(kscfg, prefix=None, suffix=None, maxlen=None): """Construct and return an image name string. This is a utility function to help create sensible name and fslabel strings. The name is constructed using the sans-prefix-and-extension kickstart filename and the supplied prefix and suffix. If the name exceeds the maxlen length supplied, the prefix is first dropped and then the kickstart filename portion is reduced until it fits. In other words, the suffix takes precedence over the kickstart portion and the kickstart portion takes precedence over the prefix.
def call(self, args): if not os.path.exists("%s/%s" % (self.instroot, args[0])): msger.warning("%s/%s" % (self.instroot, args[0])) raise errors.KsError("Unable to run %s!" % (args)) subprocess.call(args, preexec_fn=self.chroot)
def _parse_kickstart(self, ksconf=None): if not ksconf: return ksconf = misc.normalize_ksfile(ksconf, self.create['release'], self.create['arch']) ks = kickstart.read_kickstart(ksconf) self.create['ks'] = ks self.create['name'] = os.path.splitext(os.path.basename(ksconf))[0] self.create['name'] = misc.build_name(ksconf, self.create['release'], self.create['name_prefix'], self.create['name_suffix']) self.create['destdir'] = self.create['outdir'] if self.create['release'] is not None: self.create['destdir'] = "%s/%s/images/%s/" % (self.create['outdir'], self.create['release'], self.create['name']) self.create['name'] = self.create['release'] + '_' + self.create['name'] if self.create['pack_to'] is not None: if '@NAME@' in self.create['pack_to']: self.create['pack_to'] = self.create['pack_to'].replace('@NAME@', self.create['name']) self.create['name'] = misc.strip_archive_suffix(self.create['pack_to']) if self.create['name'] is None: raise errors.CreatorError("Not supported archive file format: %s" % self.create['pack_to']) if not self.create['logfile']: self.create['logfile'] = os.path.join(self.create['destdir'], self.create['name'] + ".log") self.create['releaselog'] = True self.set_logfile() elif self.create['pack_to'] is not None: if '@NAME@' in self.create['pack_to']: self.create['pack_to'] = self.create['pack_to'].replace('@NAME@', self.create['name']) self.create['name'] = misc.strip_archive_suffix(self.create['pack_to']) if self.create['name'] is None: raise errors.CreatorError("Not supported archive file format: %s" % self.create['pack_to']) msger.info("Retrieving repo metadata:") ksrepos = kickstart.get_repos(ks, self.create['extrarepos'], self.create['ignore_ksrepo']) if not ksrepos: raise errors.KsError('no valid repos found in ks file') for repo in ksrepos: if hasattr(repo, 'baseurl') and repo.baseurl.startswith("file:"): repourl = repo.baseurl.replace('file:', '') repourl = "/%s" % repourl.lstrip('/') self.create['localrepos'].append(repourl) self.create['repomd'] = misc.get_metadata_from_repos( ksrepos, self.create['cachedir']) kstpkrepos = kickstart.get_tpkrepos(ks) if kstpkrepos: for tpk_repo in kstpkrepos: if hasattr(tpk_repo,'baseurl') and tpk_repo.baseurl.startswith("file:"): tpk_repourl = tpk_repo.baseurl.replace('file:','') tpk_repourl = "/%s" % tpk_repourl.lstrip('/') self.create['localtpkrepos'].append(tpk_repourl) msger.raw(" DONE") target_archlist, archlist = misc.get_arch(self.create['repomd']) if self.create['arch']: if self.create['arch'] not in archlist: raise errors.ConfigError("Invalid arch %s for repository. " "Valid arches: %s" \ % (self.create['arch'], ', '.join(archlist))) else: if len(target_archlist) == 1: self.create['arch'] = str(target_archlist[0]) msger.info("Use detected arch %s." % target_archlist[0]) else: raise errors.ConfigError("Please specify a valid arch, " "the choice can be: %s" \ % ', '.join(archlist)) kickstart.resolve_groups(self.create, self.create['repomd']) # check selinux, it will block arm and btrfs image creation misc.selinux_check(self.create['arch'], [p.fstype for p in ks.handler.partition.partitions])