def provision_system(fqdn): system = _get_system_by_FQDN(fqdn) if not system.can_configure_netboot(identity.current.user): raise Forbidden403('Cannot provision system') data = read_json_request(request) with convert_internal_errors(): if not data['distro_tree'] or 'id' not in data['distro_tree']: raise ValueError('No distro tree specified') distro_tree = DistroTree.by_id(data['distro_tree']['id']) user = identity.current.user if user.rootpw_expired: raise ValueError('Your root password has expired, you must ' 'change or clear it in order to provision.') redirect(u"/view/%s" % system.fqdn) install_options = system.manual_provision_install_options(distro_tree)\ .combined_with(InstallOptions.from_strings(data.get('ks_meta'), data.get('koptions'), data.get('koptions_post'))) if 'ks' not in install_options.kernel_options: kickstart = generate_kickstart(install_options, distro_tree=distro_tree, system=system, user=user) install_options.kernel_options['ks'] = kickstart.link system.configure_netboot(distro_tree, install_options.kernel_options_str, service=u'HTTP') system.record_activity(user=identity.current.user, service=u'HTTP', action=u'Provision', field=u'Distro Tree', new=unicode(distro_tree)) if data.get('reboot'): system.action_power(action=u'reboot', service=u'HTTP') # in future "installations" will be a real thing in our model, # but for now we have nothing to return return 'Provisioned', 201
def install_options(self): """ Yields install options for this distro tree, as well as any inherited from the OS major level. """ osmajor = self.distro.osversion.osmajor yield osmajor.default_install_options() # arch=None means apply to all arches if None in osmajor.install_options_by_arch: op = osmajor.install_options_by_arch[None] yield InstallOptions.from_strings(op.ks_meta, op.kernel_options, op.kernel_options_post) if self.arch in osmajor.install_options_by_arch: opa = osmajor.install_options_by_arch[self.arch] yield InstallOptions.from_strings(opa.ks_meta, opa.kernel_options, opa.kernel_options_post) yield InstallOptions.from_strings(self.ks_meta, self.kernel_options, self.kernel_options_post)
def install_options_for_distro(osmajor_name, osminor, variant, arch): sources = [] sources.append(global_install_options()) sources.append(default_install_options_for_distro( osmajor_name, osminor, variant, arch)) try: osmajor = OSMajor.by_name(osmajor_name) except NoResultFound: pass # not known to Beaker else: # arch=None means apply to all arches if None in osmajor.install_options_by_arch: op = osmajor.install_options_by_arch[None] sources.append(InstallOptions.from_strings( op.ks_meta, op.kernel_options, op.kernel_options_post)) if arch in osmajor.install_options_by_arch: opa = osmajor.install_options_by_arch[arch] sources.append(InstallOptions.from_strings( opa.ks_meta, opa.kernel_options, opa.kernel_options_post)) return InstallOptions.reduce(sources)
def install_options(self): """ Yields install options for this distro tree, as well as any inherited from the OS major level. """ osmajor = self.distro.osversion.osmajor osminor = self.distro.osversion.osminor # set arch specific default netboot loader paths # relative to the TFTP root directory netbootloader = {'i386': 'pxelinux.0', # We can't distinguish between UEFI and BIOS systems at this level # so, we default to pxelinux.0 'x86_64': 'pxelinux.0', 'ia64': 'elilo-ia64.efi', 'ppc': 'yaboot', 'ppc64': 'boot/grub2/powerpc-ieee1275/core.elf', 'ppc64le': 'boot/grub2/powerpc-ieee1275/core.elf', 'aarch64': 'aarch64/bootaa64.efi', } name, version = osmajor.name, osmajor.number rhel = False if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient', 'RedHatEnterpriseLinuxServerGrid', 'CentOS'): rhel = version if rhel and (int(rhel) <= 6 or (int(rhel) == 7 and osminor == '0')): netbootloader['ppc64'] = 'yaboot' netbootloader['ppc64le'] = 'yaboot' # for s390, s390x and armhfp, we default to '' kernel_options = {'netbootloader': netbootloader.get(self.arch.arch, '')} if self.arch.arch in ['ppc', 'ppc64', 'ppc64le']: kernel_options['leavebootorder'] = None ks_meta = {'conflicts_groups' : []} if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient'): if int(rhel) >= 5: ks_meta['conflicts_groups'] = ["conflicts"] if (int(rhel) >= 6) and self.variant: ks_meta['conflicts_groups'] = ["conflicts-%s" % self.variant.lower()] if (name == 'CentOS') and (int(rhel) >= 6): ks_meta['conflicts_groups'] = [ "conflicts-client", "conflicts-server", "conflicts-workstation", ] yield InstallOptions(ks_meta, kernel_options, {}) yield osmajor.default_install_options() # arch=None means apply to all arches if None in osmajor.install_options_by_arch: op = osmajor.install_options_by_arch[None] yield InstallOptions.from_strings(op.ks_meta, op.kernel_options, op.kernel_options_post) if self.arch in osmajor.install_options_by_arch: opa = osmajor.install_options_by_arch[self.arch] yield InstallOptions.from_strings(opa.ks_meta, opa.kernel_options, opa.kernel_options_post) yield InstallOptions.from_strings(self.ks_meta, self.kernel_options, self.kernel_options_post)
def main(*args): parser = optparse.OptionParser('usage: %prog [options]', description=__description__, version=__version__) parser.add_option('-u', '--user', metavar='USERNAME', help='The user we are creating a kickstart for', default='admin') parser.add_option('-r', '--recipe-id', metavar='ID', help='Recreate kickstart based on recipe ID') parser.add_option('-d', '--distro-tree-id', metavar='ID', help='Recreate kickstart based on distro ID') parser.add_option('-t', '--template-dir', metavar='DIR', help='Retrieve templates from DIR') parser.add_option('-f', '--system', metavar='FQDN', help='Generate kickstart for system identified by FQDN') parser.add_option('-m', '--ks-meta', metavar='OPTIONS', help='Kickstart meta data') parser.add_option('-p', '--kernel-options-post', metavar='OPTIONS', help='Kernel options post') options, args = parser.parse_args(*args) ks_meta = options.ks_meta koptions_post = options.kernel_options_post template_dir = options.template_dir if template_dir: add_to_template_searchpath(template_dir) if not options.recipe_id: if not options.distro_tree_id and not options.system: parser.error('Must specify either a recipe or a distro tree and system') elif not options.distro_tree_id: parser.error('Must specify a distro tree id when passing in a system') elif not options.system: parser.error('Must specify a system when not specifying a recipe') load_config_or_exit() with session.begin(): user = User.by_user_name(options.user) ks_appends = None recipe = None distro_tree = None system = None install_options = None if options.distro_tree_id: try: distro_tree = DistroTree.by_id(options.distro_tree_id) except NoResultFound: raise RuntimeError("Distro tree id '%s' does not exist" % options.distro_tree_id) if options.system: fqdn = options.system try: system = System.by_fqdn(fqdn, user) except NoResultFound: raise RuntimeError("System '%s' does not exist" % fqdn) if distro_tree and not options.recipe_id: install_options = system.manual_provision_install_options(distro_tree)\ .combined_with(InstallOptions.from_strings(ks_meta, None, koptions_post)) if options.recipe_id: try: recipe = Recipe.by_id(options.recipe_id) except NoResultFound: raise RuntimeError("Recipe id '%s' does not exist" % options.recipe_id) if not recipe.resource and not options.system: raise RuntimeError('Recipe must have (or had) a resource' ' assigned to it') if not system: system = getattr(recipe.resource, 'system', None) if not distro_tree: distro_tree = recipe.distro_tree install_options = InstallOptions.reduce(chain( [global_install_options()], distro_tree.install_options(), system.install_options(distro_tree), [recipe.generated_install_options(), InstallOptions.from_strings(recipe.ks_meta, recipe.kernel_options, recipe.kernel_options_post), InstallOptions.from_strings(ks_meta, None, koptions_post)])) ks_appends = [ks_append.ks_append for ks_append \ in recipe.ks_appends] user = recipe.recipeset.job.owner # Render the kickstart rendered_kickstart = generate_kickstart(install_options, distro_tree=distro_tree, system=system, user=user, recipe=recipe, ks_appends=ks_appends) kickstart = rendered_kickstart.kickstart print kickstart
systems = XmlHost.from_string(recipe.host_requires).apply_filter( System.query) except StandardError, e: raise BX(_('Error in hostRequires: %s' % e)) recipe.whiteboard = xmlrecipe.whiteboard or None #'' -> NULL for DB recipe.kickstart = xmlrecipe.kickstart if xmlrecipe.autopick: recipe.autopick_random = xmlrecipe.autopick.random if xmlrecipe.watchdog: recipe.panic = xmlrecipe.watchdog.panic recipe.ks_meta = xmlrecipe.ks_meta recipe.kernel_options = xmlrecipe.kernel_options recipe.kernel_options_post = xmlrecipe.kernel_options_post # try parsing install options to make sure there is no syntax error try: InstallOptions.from_strings(recipe.ks_meta, recipe.kernel_options, recipe.kernel_options_post) except Exception as e: raise BX(_('Error parsing ks_meta: %s' % e)) recipe.role = xmlrecipe.role if xmlrecipe.reservesys: recipe.reservation_request = RecipeReservationRequest( xmlrecipe.reservesys.duration) custom_packages = set() for xmlpackage in xmlrecipe.packages(): package = TaskPackage.lazy_create(package='%s' % xmlpackage.name) custom_packages.add(package) for installPackage in xmlrecipe.installPackages(): package = TaskPackage.lazy_create(package='%s' % installPackage) custom_packages.add(package) recipe.custom_packages = list(custom_packages) for xmlrepo in xmlrecipe.iter_repos():
def install_options(self): return InstallOptions.from_strings(self.ks_meta, self.kernel_options, self.kernel_options_post)
def default_install_options_for_distro(osmajor_name, osminor, variant, arch): """ Returns the default install options supplied by Beaker (rather than the admin) based on some hardcoded OS major names. This is where installer feature test variables are populated. """ # Some convenience variables to make the name-based checks simpler: name, version = split_osmajor_name_version(osmajor_name) rhel, fedora = False, False if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient', 'RedHatEnterpriseLinuxServerGrid', 'RedHatEnterpriseLinuxAlternateArchitectures', 'CentOS'): rhel = version if osmajor_name in ('RedHatStorage2', 'RedHatStorageSoftwareAppliance3', 'RedHatGlusterStorage3'): rhel = '6' if osmajor_name in ('RHVH4', ): rhel = '7' if name == 'Fedora': fedora = version # We default to assuming all features are present, with features # conditionally turned off if needed. That way, unrecognised custom # distros will be assumed to support all features. The admin can # override these in OS major or distro install options if necessary. ks_meta = {} # Default harness is set to restraint. We opt out of restraint for any # distro prior to RHEL8 and Fedora 29. ks_meta['harness'] = 'restraint-rhts' if (rhel and int(rhel) < 8 or \ fedora and fedora != 'rawhide' and int(fedora) < 29): ks_meta['harness'] = 'beah' ks_meta['install_task_requires'] = True # %end ks_meta['end'] = '%end' if rhel in ('3', '4', '5'): ks_meta['end'] = '' # key option for RHEL 5 if rhel and int(rhel) == 5: ks_meta['has_key'] = True # autopart --type ks_meta['has_autopart_type'] = True if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 18): del ks_meta['has_autopart_type'] # chrony ks_meta['has_chrony'] = True if rhel in ('3', '4', '5', '6'): del ks_meta['has_chrony'] # DHCP option 26 ks_meta['has_dhcp_mtu_support'] = True if rhel in ('3', '4'): del ks_meta['has_dhcp_mtu_support'] # GPT on BIOS ks_meta['has_gpt_bios_support'] = True if rhel in ('3', '4', '5', '6'): del ks_meta['has_gpt_bios_support'] # bootloader --leavebootorder ks_meta['has_leavebootorder'] = True if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 18): del ks_meta['has_leavebootorder'] # repo --cost ks_meta['has_repo_cost'] = True if rhel in ('3', '4', '5'): del ks_meta['has_repo_cost'] # reqpart ks_meta['has_reqpart'] = True if rhel == '7' and osminor in ('0', '1'): # added in RHEL7.2 del ks_meta['has_reqpart'] if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 23): del ks_meta['has_reqpart'] # systemd vs. SysV init ks_meta['has_systemd'] = True if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 15): del ks_meta['has_systemd'] # unsupported_hardware ks_meta['has_unsupported_hardware'] = True if rhel in ('3', '4', '5'): del ks_meta['has_unsupported_hardware'] # yum if rhel == '3': ks_meta['yum'] = 'yum-2.2.2-1.rhts.EL3.noarch.rpm' elif rhel == '4': ks_meta['yum'] = 'yum-2.2.2-1.rhts.EL4.noarch.rpm' # extra options for 'yum install' invocations if rhel in ('3', '4'): ks_meta['yum_install_extra_opts'] = '-d 1' # mode if rhel == '6': ks_meta['mode'] = 'cmdline' if rhel in ('4', '5'): ks_meta['mode'] = '' # docker package name ks_meta['docker_package'] = 'docker' if (fedora and fedora != 'rawhide' and int(fedora) < 22) or (rhel and int(rhel) <= 6): ks_meta['docker_package'] = 'docker-io' # recommended boot partition size if rhel in ('5', '6'): ks_meta['boot_partition_size'] = 250 elif rhel in ('3', '4'): ks_meta['boot_partition_size'] = 200 # names of package groups containing conflicts if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient'): if int(rhel) >= 5: ks_meta['conflicts_groups'] = ['conflicts'] if (int(rhel) >= 6) and variant: ks_meta['conflicts_groups'] = ['conflicts-%s' % variant.lower()] elif name == 'CentOS' and int(rhel) >= 6: ks_meta['conflicts_groups'] = [ 'conflicts-client', 'conflicts-server', 'conflicts-workstation', ] else: ks_meta['conflicts_groups'] = [] # clearpart --cdl if arch.arch == 's390x' and (rhel == '7' and int(osminor) >= 6 or rhel == '8' and int(osminor) >= 0): ks_meta['has_clearpart_cdl'] = True ks_meta[ 'has_ignoredisk_interactive'] = False # --interactive is deprecated if (rhel and int(rhel) < 8) or (fedora and fedora != 'rawhide' and int(fedora) < 29): ks_meta['has_ignoredisk_interactive'] = True # Remove Fedora disabled root/password ssh combination # introduced in Fedora 31 if fedora and (fedora == 'rawhide' or int(fedora) > 30): ks_meta['disabled_root_access'] = True kernel_options = {} # set arch specific default netboot loader paths # relative to the TFTP root directory netbootloader = { 'i386': 'pxelinux.0', # We can't distinguish between UEFI and BIOS systems at this level # so, we default to pxelinux.0 'x86_64': 'pxelinux.0', 'ia64': 'elilo-ia64.efi', 'ppc': 'yaboot', 'ppc64': 'boot/grub2/powerpc-ieee1275/core.elf', 'ppc64le': 'boot/grub2/powerpc-ieee1275/core.elf', 'aarch64': 'aarch64/bootaa64.efi', } if rhel and (int(rhel) <= 6 or (int(rhel) == 7 and osminor == '0')): netbootloader['ppc64'] = 'yaboot' netbootloader['ppc64le'] = 'yaboot' # for s390, s390x and armhfp, we default to '' kernel_options['netbootloader'] = netbootloader.get(arch.arch, '') if arch.arch in ['ppc', 'ppc64', 'ppc64le']: kernel_options['leavebootorder'] = None return InstallOptions(ks_meta, kernel_options, {})
# try evaluating the host_requires, to make sure it's valid systems = XmlHost.from_string(recipe.host_requires).apply_filter(System.query) except StandardError, e: raise BX(_('Error in hostRequires: %s' % e)) recipe.whiteboard = xmlrecipe.whiteboard or None #'' -> NULL for DB recipe.kickstart = xmlrecipe.kickstart if xmlrecipe.autopick: recipe.autopick_random = xmlrecipe.autopick.random if xmlrecipe.watchdog: recipe.panic = xmlrecipe.watchdog.panic recipe.ks_meta = xmlrecipe.ks_meta recipe.kernel_options = xmlrecipe.kernel_options recipe.kernel_options_post = xmlrecipe.kernel_options_post # try parsing install options to make sure there is no syntax error try: InstallOptions.from_strings(recipe.ks_meta, recipe.kernel_options, recipe.kernel_options_post) except Exception as e: raise BX(_('Error parsing ks_meta: %s' % e)) recipe.role = xmlrecipe.role if xmlrecipe.reservesys: recipe.reservation_request = RecipeReservationRequest(xmlrecipe.reservesys.duration) custom_packages = set() for xmlpackage in xmlrecipe.packages(): package = TaskPackage.lazy_create(package='%s' % xmlpackage.name) custom_packages.add(package) for installPackage in xmlrecipe.installPackages(): package = TaskPackage.lazy_create(package='%s' % installPackage) custom_packages.add(package) recipe.custom_packages = list(custom_packages) for xmlrepo in xmlrecipe.iter_repos(): recipe.repos.append(RecipeRepo(name=xmlrepo.name, url=xmlrepo.url))
def install_options(self): """ Yields install options for this distro tree, as well as any inherited from the OS major level. """ osmajor = self.distro.osversion.osmajor osminor = self.distro.osversion.osminor # set arch specific default netboot loader paths # relative to the TFTP root directory netbootloader = { 'i386': 'pxelinux.0', # We can't distinguish between UEFI and BIOS systems at this level # so, we default to pxelinux.0 'x86_64': 'pxelinux.0', 'ia64': 'elilo-ia64.efi', 'ppc': 'yaboot', 'ppc64': 'boot/grub2/powerpc-ieee1275/core.elf', 'ppc64le': 'boot/grub2/powerpc-ieee1275/core.elf', 'aarch64': 'aarch64/bootaa64.efi', } name, version = osmajor.name, osmajor.number rhel = False if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient', 'RedHatEnterpriseLinuxServerGrid', 'CentOS'): rhel = version if rhel and (int(rhel) <= 6 or (int(rhel) == 7 and osminor == '0')): netbootloader['ppc64'] = 'yaboot' netbootloader['ppc64le'] = 'yaboot' # for s390, s390x and armhfp, we default to '' kernel_options = { 'netbootloader': netbootloader.get(self.arch.arch, '') } if self.arch.arch in ['ppc', 'ppc64', 'ppc64le']: kernel_options['leavebootorder'] = None ks_meta = {'conflicts_groups': []} if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient'): if int(rhel) >= 5: ks_meta['conflicts_groups'] = ["conflicts"] if (int(rhel) >= 6) and self.variant: ks_meta['conflicts_groups'] = [ "conflicts-%s" % self.variant.lower() ] if (name == 'CentOS') and (int(rhel) >= 6): ks_meta['conflicts_groups'] = [ "conflicts-client", "conflicts-server", "conflicts-workstation", ] yield InstallOptions(ks_meta, kernel_options, {}) yield osmajor.default_install_options() # arch=None means apply to all arches if None in osmajor.install_options_by_arch: op = osmajor.install_options_by_arch[None] yield InstallOptions.from_strings(op.ks_meta, op.kernel_options, op.kernel_options_post) if self.arch in osmajor.install_options_by_arch: opa = osmajor.install_options_by_arch[self.arch] yield InstallOptions.from_strings(opa.ks_meta, opa.kernel_options, opa.kernel_options_post) yield InstallOptions.from_strings(self.ks_meta, self.kernel_options, self.kernel_options_post)
def default_install_options(self): """ Returns the default install options supplied by Beaker (rather than the admin) based on some hardcoded OS major names. This is where installer feature test variables are populated. """ # We default to assuming all features are present, with features # conditionally turned off if needed. That way, unrecognised custom # distros will be assumed to support all features. The admin can # override these in OS major or distro install options if necessary. ks_meta = {} # Some convenience variables to make the name-based checks simpler: name, version = self._split() rhel, fedora = False, False if name in ('RedHatEnterpriseLinux', 'RedHatEnterpriseLinuxServer', 'RedHatEnterpriseLinuxClient', 'RedHatEnterpriseLinuxServerGrid', 'CentOS'): rhel = version if self.osmajor in ('RedHatStorage2', 'RedHatStorageSoftwareAppliance3', 'RedHatGlusterStorage3'): rhel = '6' if name == 'Fedora': fedora = version # %end ks_meta['end'] = '%end' if rhel in ('3', '4', '5'): ks_meta['end'] = '' # key option for RHEL 5 if rhel and int(rhel) == 5: ks_meta['has_key'] = True # autopart --type ks_meta['has_autopart_type'] = True if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 18): del ks_meta['has_autopart_type'] # chrony ks_meta['has_chrony'] = True if rhel in ('3', '4', '5', '6'): del ks_meta['has_chrony'] # DHCP option 26 ks_meta['has_dhcp_mtu_support'] = True if rhel in ('3', '4'): del ks_meta['has_dhcp_mtu_support'] # GPT on BIOS ks_meta['has_gpt_bios_support'] = True if rhel in ('3', '4', '5', '6'): del ks_meta['has_gpt_bios_support'] # bootloader --leavebootorder ks_meta['has_leavebootorder'] = True if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 18): del ks_meta['has_leavebootorder'] # repo --cost ks_meta['has_repo_cost'] = True if rhel in ('3', '4', '5'): del ks_meta['has_repo_cost'] # systemd vs. SysV init ks_meta['has_systemd'] = True if rhel in ('3', '4', '5', '6') or \ (fedora and fedora != 'rawhide' and int(fedora) < 15): del ks_meta['has_systemd'] # unsupported_hardware ks_meta['has_unsupported_hardware'] = True if rhel in ('3', '4', '5'): del ks_meta['has_unsupported_hardware'] # yum if rhel == '3': ks_meta['yum'] = 'yum-2.2.2-1.rhts.EL3.noarch.rpm' elif rhel == '4': ks_meta['yum'] = 'yum-2.2.2-1.rhts.EL4.noarch.rpm' # mode if rhel == '6': ks_meta['mode'] = 'cmdline' if rhel in ('4', '5'): ks_meta['mode'] = '' # docker package name ks_meta['docker_package'] = 'docker' if (fedora and fedora != 'rawhide' and int(fedora) < 22) or (rhel and int(rhel) <= 6): ks_meta['docker_package'] = 'docker-io' # recommended boot partition size if rhel in ('5', '6'): ks_meta['boot_partition_size'] = 250 elif rhel in ('3', '4'): ks_meta['boot_partition_size'] = 200 return InstallOptions(ks_meta, {}, {})
def main(*args): parser = optparse.OptionParser('usage: %prog [options]', description=__description__, version=__version__) parser.add_option('-u', '--user', metavar='USERNAME', help='The user we are creating a kickstart for', default='admin') parser.add_option('-r', '--recipe-id', metavar='ID', help='Recreate kickstart based on recipe ID') parser.add_option('-d', '--distro-tree-id', metavar='ID', help='Recreate kickstart based on distro ID') parser.add_option('-t', '--template-dir', metavar='DIR', help='Retrieve templates from DIR') parser.add_option('-f', '--system', metavar='FQDN', help='Generate kickstart for system identified by FQDN') parser.add_option('-m', '--ks-meta', metavar='OPTIONS', help='Kickstart meta data') parser.add_option('-p', '--kernel-options-post', metavar='OPTIONS', help='Kernel options post') options, args = parser.parse_args(*args) ks_meta = options.ks_meta koptions_post = options.kernel_options_post template_dir = options.template_dir if template_dir: add_to_template_searchpath(template_dir) if not options.recipe_id: if not options.distro_tree_id and not options.system: parser.error( 'Must specify either a recipe or a distro tree and system') elif not options.distro_tree_id: parser.error( 'Must specify a distro tree id when passing in a system') elif not options.system: parser.error('Must specify a system when not specifying a recipe') load_config_or_exit() with session.begin(): user = User.by_user_name(options.user) ks_appends = None recipe = None distro_tree = None system = None install_options = None if options.distro_tree_id: try: distro_tree = DistroTree.by_id(options.distro_tree_id) except NoResultFound: raise RuntimeError("Distro tree id '%s' does not exist" % options.distro_tree_id) if options.system: fqdn = options.system try: system = System.by_fqdn(fqdn, user) except NoResultFound: raise RuntimeError("System '%s' does not exist" % fqdn) if distro_tree and not options.recipe_id: install_options = system.manual_provision_install_options(distro_tree)\ .combined_with(InstallOptions.from_strings(ks_meta, None, koptions_post)) if options.recipe_id: try: recipe = Recipe.by_id(options.recipe_id) except NoResultFound: raise RuntimeError("Recipe id '%s' does not exist" % options.recipe_id) if not recipe.resource and not options.system: raise RuntimeError('Recipe must have (or had) a resource' ' assigned to it') if not system: system = getattr(recipe.resource, 'system', None) if not distro_tree: distro_tree = recipe.distro_tree install_options = InstallOptions.reduce( chain([global_install_options()], distro_tree.install_options(), system.install_options(distro_tree), [ recipe.generated_install_options(), InstallOptions.from_strings( recipe.ks_meta, recipe.kernel_options, recipe.kernel_options_post), InstallOptions.from_strings(ks_meta, None, koptions_post) ])) ks_appends = [ks_append.ks_append for ks_append \ in recipe.ks_appends] user = recipe.recipeset.job.owner # Render the kickstart rendered_kickstart = generate_kickstart(install_options, distro_tree=distro_tree, system=system, user=user, recipe=recipe, ks_appends=ks_appends) kickstart = rendered_kickstart.kickstart print kickstart
def provision(self, fqdn, distro_tree_id, ks_meta=None, kernel_options=None, kernel_options_post=None, kickstart=None, reboot=True): """ Provisions a system with the given distro tree and options. The *ks_meta*, *kernel_options*, and *kernel_options_post* arguments override the default values configured for the system. For example, if the default kernel options for the system/distro are 'console=ttyS0 ksdevice=eth0', and the caller passes 'ksdevice=eth1' for *kernel_options*, the kernel options used will be 'console=ttyS0 ksdevice=eth1'. :param distro_tree_id: numeric id of distro tree to be provisioned :type distro_tree_id: int :param ks_meta: kickstart options :type ks_meta: str :param kernel_options: kernel options for installation :type kernel_options: str :param kernel_options_post: kernel options for after installation :type kernel_options_post: str :param kickstart: complete kickstart :type kickstart: str :param reboot: whether to reboot the system after applying Cobbler changes :type reboot: bool .. versionadded:: 0.6 .. versionchanged:: 0.6.10 System-specific kickstart/kernel options are now obeyed. .. versionchanged:: 0.9 *distro_install_name* parameter is replaced with *distro_tree_id*. See :meth:`distrotrees.filter`. """ system = System.by_fqdn(fqdn, identity.current.user) if not system.user == identity.current.user: raise BX(_(u'Reserve a system before provisioning')) distro_tree = DistroTree.by_id(distro_tree_id) # sanity check: does the distro tree apply to this system? if not system.compatible_with_distro_tree(distro_tree): raise BX( _(u'Distro tree %s cannot be provisioned on %s') % (distro_tree, system.fqdn)) if not system.lab_controller: raise BX(_(u'System is not attached to a lab controller')) if not distro_tree.url_in_lab(system.lab_controller): raise BX( _(u'Distro tree %s is not available in lab %s') % (distro_tree, system.lab_controller)) if identity.current.user.rootpw_expired: raise BX( _('Your root password has expired, please change or clear it in order to submit jobs.' )) # ensure system-specific defaults are used # (overriden by this method's arguments) options = system.manual_provision_install_options(distro_tree)\ .combined_with(InstallOptions.from_strings( ks_meta or '', kernel_options or '', kernel_options_post or '')) if 'ks' not in options.kernel_options: rendered_kickstart = generate_kickstart(options, distro_tree=distro_tree, system=system, user=identity.current.user, kickstart=kickstart) options.kernel_options['ks'] = rendered_kickstart.link system.configure_netboot(distro_tree, options.kernel_options_str, service=u'XMLRPC') system.record_activity(user=identity.current.user, service=u'XMLRPC', action=u'Provision', field=u'Distro Tree', old=u'', new=u'Success: %s' % distro_tree) if reboot: system.action_power(action='reboot', service=u'XMLRPC') return system.fqdn # because turbogears makes us return something
def main(*args): parser = optparse.OptionParser('usage: %prog [options]', description=__description__, version=__version__) parser.add_option('-u', '--user', metavar='USERNAME', help='The user we are creating a kickstart for', default='admin') parser.add_option('-r', '--recipe-id', metavar='ID', help='Recreate kickstart based on recipe ID') parser.add_option('-d', '--distro-tree-id', metavar='ID', help='Recreate kickstart based on distro ID') parser.add_option('-t', '--template-dir', metavar='DIR', help='Retrieve templates from DIR') parser.add_option('-f', '--system', metavar='FQDN', help='Generate kickstart for system identified by FQDN') parser.add_option('-m', '--ks-meta', metavar='OPTIONS', default='', help='Kickstart meta data') parser.add_option('-p', '--kernel-options-post', metavar='OPTIONS', default='', help='Kernel options post') options, args = parser.parse_args(*args) ks_meta = options.ks_meta.decode(sys.getfilesystemencoding()) koptions_post = options.kernel_options_post.decode(sys.getfilesystemencoding()) template_dir = options.template_dir if template_dir: add_to_template_searchpath(template_dir) if not options.recipe_id: if not options.distro_tree_id and not options.system: parser.error('Must specify either a recipe or a distro tree and system') elif not options.distro_tree_id: parser.error('Must specify a distro tree id when passing in a system') elif not options.system: parser.error('Must specify a system when not specifying a recipe') load_config_or_exit() with session.begin(): user = User.by_user_name(options.user.decode(sys.getfilesystemencoding())) ks_appends = None recipe = None distro_tree = None system = None install_options = None if options.distro_tree_id: try: distro_tree = DistroTree.by_id(options.distro_tree_id) except NoResultFound: raise RuntimeError("Distro tree id '%s' does not exist" % options.distro_tree_id) if options.system: fqdn = options.system.decode(sys.getfilesystemencoding()) try: system = System.by_fqdn(fqdn, user) except DatabaseLookupError: raise RuntimeError("System '%s' does not exist" % fqdn) if distro_tree and not options.recipe_id: install_options = system.manual_provision_install_options(distro_tree)\ .combined_with(InstallOptions.from_strings(ks_meta, None, koptions_post)) if options.recipe_id: try: recipe = Recipe.by_id(options.recipe_id) except NoResultFound: raise RuntimeError("Recipe id '%s' does not exist" % options.recipe_id) if not recipe.resource and not options.system: raise RuntimeError('Recipe must have (or had) a resource' ' assigned to it') if not system: system = getattr(recipe.resource, 'system', None) if not distro_tree: distro_tree = recipe.distro_tree sources = [] # if distro_tree is specified, distro_tree overrides recipe osmajor = distro_tree.distro.osversion.osmajor.osmajor if distro_tree else recipe.installation.osmajor osminor = distro_tree.distro.osversion.osminor if distro_tree else recipe.installation.osminor variant = distro_tree.variant if distro_tree else recipe.installation.variant arch = distro_tree.arch if distro_tree else recipe.installation.arch sources.append(install_options_for_distro(osmajor, osminor, variant, arch)) if distro_tree: sources.append(distro_tree.install_options()) sources.extend(system.install_options(arch, osmajor, osminor)) sources.append(recipe.generated_install_options()) sources.append(InstallOptions.from_strings(recipe.ks_meta, recipe.kernel_options, recipe.kernel_options_post)) sources.append(InstallOptions.from_strings(ks_meta, None, koptions_post)) install_options = InstallOptions.reduce(sources) ks_appends = [ks_append.ks_append for ks_append \ in recipe.ks_appends] user = recipe.recipeset.job.owner # Render the kickstart installation = recipe.installation if recipe and recipe.installation else \ FakeInstallation(distro_tree.distro.osversion.osmajor.osmajor, distro_tree.distro.osversion.osminor, distro_tree.distro.name, distro_tree.variant, distro_tree.arch, distro_tree.url_in_lab(lab_controller=system.lab_controller)) rendered_kickstart = generate_kickstart(install_options=install_options, distro_tree=distro_tree, installation=installation, system=system, user=user, recipe=recipe, ks_appends=ks_appends) kickstart = rendered_kickstart.kickstart print kickstart
def provision(self, fqdn, distro_tree_id, ks_meta=None, kernel_options=None, kernel_options_post=None, kickstart=None, reboot=True): """ Provisions a system with the given distro tree and options. The *ks_meta*, *kernel_options*, and *kernel_options_post* arguments override the default values configured for the system. For example, if the default kernel options for the system/distro are 'console=ttyS0 ksdevice=eth0', and the caller passes 'ksdevice=eth1' for *kernel_options*, the kernel options used will be 'console=ttyS0 ksdevice=eth1'. :param distro_tree_id: numeric id of distro tree to be provisioned :type distro_tree_id: int :param ks_meta: kickstart options :type ks_meta: str :param kernel_options: kernel options for installation :type kernel_options: str :param kernel_options_post: kernel options for after installation :type kernel_options_post: str :param kickstart: complete kickstart :type kickstart: str :param reboot: whether to reboot the system after applying Cobbler changes :type reboot: bool .. versionadded:: 0.6 .. versionchanged:: 0.6.10 System-specific kickstart/kernel options are now obeyed. .. versionchanged:: 0.9 *distro_install_name* parameter is replaced with *distro_tree_id*. See :meth:`distrotrees.filter`. """ system = System.by_fqdn(fqdn, identity.current.user) if not system.can_provision_now(identity.current.user): raise BX(_(u'User %s has insufficient permissions to provision %s') % (identity.current.user.user_name, system.fqdn)) if not system.user == identity.current.user: raise BX(_(u'Reserve a system before provisioning')) distro_tree = DistroTree.by_id(distro_tree_id) # sanity check: does the distro tree apply to this system? if distro_tree.systems().filter(System.id == system.id).count() < 1: raise BX(_(u'Distro tree %s cannot be provisioned on %s') % (distro_tree, system.fqdn)) if identity.current.user.rootpw_expired: raise BX(_('Your root password has expired, please change or clear it in order to submit jobs.')) # ensure system-specific defaults are used # (overriden by this method's arguments) options = system.install_options(distro_tree).combined_with( InstallOptions.from_strings(ks_meta or '', kernel_options or '', kernel_options_post or '')) if 'ks' not in options.kernel_options: rendered_kickstart = generate_kickstart(options, distro_tree=distro_tree, system=system, user=identity.current.user, kickstart=kickstart) options.kernel_options['ks'] = rendered_kickstart.link system.configure_netboot(distro_tree, options.kernel_options_str, service=u'XMLRPC') system.activity.append(SystemActivity(user=identity.current.user, service=u'XMLRPC', action=u'Provision', field_name=u'Distro Tree', old_value=u'', new_value=u'Success: %s' % distro_tree)) if reboot: system.action_power(action='reboot', service=u'XMLRPC') return system.fqdn # because turbogears makes us return something