Example #1
0
    def add_objects_not_on_local(self, obj_type):
        """
        Add objects locally which are not present on the slave but on the master.

        :param obj_type:
        """
        locals = utils.lod_to_dod(self.local_data[obj_type], "uid")
        remotes = utils.lod_sort_by_key(self.remote_data[obj_type], "depth")

        for rdata in remotes:

            # do not add the system if it is not on the transfer list
            if not rdata["name"] in self.must_include[obj_type]:
                continue

            if not rdata["uid"] in locals:
                creator = getattr(self.api, "new_%s" % obj_type)
                newobj = creator()
                newobj.from_dict(utils.revert_strip_none(rdata))
                try:
                    self.logger.info("adding %s %s" % (obj_type, rdata["name"]))
                    if not self.api.add_item(obj_type, newobj):
                        self.logger.error("failed to add %s %s" % (obj_type, rdata["name"]))
                except Exception:
                    utils.log_exc()
Example #2
0
    def replace_objects_newer_on_remote(self, obj_type):
        """
        Replace objects which are newer on the local slave then on the remote slave

        :param obj_type: The type of object to synchronize.
        """
        locals = utils.lod_to_dod(self.local_data[obj_type], "uid")
        remotes = utils.lod_to_dod(self.remote_data[obj_type], "uid")

        for (ruid, rdata) in list(remotes.items()):
            # do not add the system if it is not on the transfer list
            if not rdata["name"] in self.must_include[obj_type]:
                continue

            if ruid in locals:
                ldata = locals[ruid]
                if ldata["mtime"] < rdata["mtime"]:

                    if ldata["name"] != rdata["name"]:
                        self.logger.info("removing %s %s" % (obj_type, ldata["name"]))
                        self.api.remove_item(obj_type, ldata["name"], recursive=True)
                    creator = getattr(self.api, "new_%s" % obj_type)
                    newobj = creator()
                    newobj.from_dict(utils.revert_strip_none(rdata))
                    try:
                        self.logger.info("updating %s %s" % (obj_type, rdata["name"]))
                        if not self.api.add_item(obj_type, newobj):
                            self.logger.error("failed to update %s %s" % (obj_type, rdata["name"]))
                    except Exception:
                        utils.log_exc()
Example #3
0
def test_revert_strip_none(input_data, expected_output):
    # Arrange

    # Act
    result = utils.revert_strip_none(input_data)

    # Assert
    assert expected_output == result
Example #4
0
    def build_kernel_options(self, system, profile, distro, image, arch,
                             autoinstall_path):
        """
        Builds the full kernel options line.
        """

        management_interface = None
        if system is not None:
            blended = utils.blender(self.api, False, system)
            # find the first management interface
            try:
                for intf in list(system.interfaces.keys()):
                    if system.interfaces[intf]["management"]:
                        management_interface = intf
                        break
            except:
                # just skip this then
                pass
        elif profile is not None:
            blended = utils.blender(self.api, False, profile)
        else:
            blended = utils.blender(self.api, False, image)

        append_line = ""
        kopts = blended.get("kernel_options", dict())
        kopts = utils.revert_strip_none(kopts)

        # SUSE and other distro specific kernel additions or modificatins
        utils.kopts_overwrite(system, distro, kopts, self.settings)

        # since network needs to be configured again (it was already in netboot) when kernel boots
        # and we choose to do it dinamically, we need to set 'ksdevice' to one of
        # the interfaces' MAC addresses in ppc systems.
        # ksdevice=bootif is not useful in yaboot, as the "ipappend" line is a pxe feature.
        if system and arch and (arch == "ppc" or arch == "ppc64"):
            for intf in list(system.interfaces.keys()):
                # use first interface with defined IP and MAC, since these are required
                # fields in a DHCP entry
                mac_address = system.interfaces[intf]['mac_address']
                ip_address = system.interfaces[intf]['ip_address']
                if mac_address and ip_address:
                    kopts['BOOTIF'] = '01-' + mac_address
                    kopts['ksdevice'] = mac_address
                    break

        # support additional initrd= entries in kernel options.
        if "initrd" in kopts:
            append_line = ",%s" % kopts.pop("initrd")
        hkopts = utils.dict_to_string(kopts)
        append_line = "%s %s" % (append_line, hkopts)

        # automatic installation file path rewriting (get URLs for local files)
        if autoinstall_path:

            # FIXME: need to make shorter rewrite rules for these URLs

            try:
                ipaddress = socket.gethostbyname_ex(blended["http_server"])[2][0]
            except socket.gaierror:
                ipaddress = blended["http_server"]
            URL_REGEX = "[a-zA-Z]*://.*"
            local_autoinstall_file = not re.match(URL_REGEX, autoinstall_path)
            if local_autoinstall_file:
                if system is not None:
                    autoinstall_path = "http://%s/cblr/svc/op/autoinstall/system/%s" % (ipaddress, system.name)
                else:
                    autoinstall_path = "http://%s/cblr/svc/op/autoinstall/profile/%s" % (ipaddress, profile.name)

            if distro.breed is None or distro.breed == "redhat":

                append_line += " kssendmac"
                append_line = "%s ks=%s" % (append_line, autoinstall_path)
                gpxe = blended["enable_gpxe"]
                if gpxe:
                    append_line = append_line.replace('ksdevice=bootif', 'ksdevice=${net0/mac}')
            elif distro.breed == "suse":
                append_line = "%s autoyast=%s" % (append_line, autoinstall_path)
                if management_interface:
                    append_line += "netdevice=%s" % management_interface
            elif distro.breed == "debian" or distro.breed == "ubuntu":
                append_line = "%s auto-install/enable=true priority=critical netcfg/choose_interface=auto url=%s" % (append_line, autoinstall_path)
                if management_interface:
                    append_line += " netcfg/choose_interface=%s" % management_interface
            elif distro.breed == "freebsd":
                append_line = "%s ks=%s" % (append_line, autoinstall_path)

                # rework kernel options for debian distros
                translations = {'ksdevice': "interface", 'lang': "locale"}
                for k, v in list(translations.items()):
                    append_line = append_line.replace("%s=" % k, "%s=" % v)

                # interface=bootif causes a failure
                append_line = append_line.replace("interface=bootif", "")
            elif distro.breed == "vmware":
                if distro.os_version.find("esxi") != -1:
                    # ESXi is very picky, it's easier just to redo the
                    # entire append line here since
                    append_line = " ks=%s %s" % (autoinstall_path, hkopts)
                    # ESXi likes even fewer options, so we remove them too
                    append_line = append_line.replace("kssendmac", "")
                else:
                    append_line = "%s vmkopts=debugLogToSerial:1 mem=512M ks=%s" % \
                        (append_line, autoinstall_path)
                # interface=bootif causes a failure
                append_line = append_line.replace("ksdevice=bootif", "")
            elif distro.breed == "xen":
                if distro.os_version.find("xenserver620") != -1:
                    img_path = os.path.join("/images", distro.name)
                    append_line = "append %s/xen.gz dom0_max_vcpus=2 dom0_mem=752M com1=115200,8n1 console=com1,vga --- %s/vmlinuz xencons=hvc console=hvc0 console=tty0 install answerfile=%s --- %s/install.img" % (img_path, img_path, autoinstall_path, img_path)
                    return append_line
            elif distro.breed == "powerkvm":
                append_line += " kssendmac"
                append_line = "%s kvmp.inst.auto=%s" % (append_line, autoinstall_path)

        if distro is not None and (distro.breed in ["debian", "ubuntu"]):
            # Hostname is required as a parameter, the one in the preseed is
            # not respected, so calculate if we have one here.
            # We're trying: first part of FQDN in hostname field, then system
            # name, then profile name.
            # In Ubuntu, this is at least used for the volume group name when
            # using LVM.
            domain = "local.lan"
            if system is not None:
                if system.hostname is not None and system.hostname != "":
                    # If this is a FQDN, grab the first bit
                    hostname = system.hostname.split(".")[0]
                    _domain = system.hostname.split(".")[1:]
                    if _domain:
                        domain = ".".join(_domain)
                else:
                    hostname = system.name
            else:
                # ubuntu at the very least does not like having underscores
                # in the hostname.
                # FIXME: Really this should remove all characters that are
                # forbidden in hostnames
                hostname = profile.name.replace("_", "")

            # At least for debian deployments configured for DHCP networking
            # this values are not used, but specifying here avoids questions
            append_line = "%s hostname=%s" % (append_line, hostname)
            append_line = "%s domain=%s" % (append_line, domain)

            # A similar issue exists with suite name, as installer requires
            # the existence of "stable" in the dists directory
            append_line = "%s suite=%s" % (append_line, distro.os_version)

        # append necessary kernel args for arm architectures
        if arch is not None and arch.startswith("arm"):
            append_line = "%s fixrtc vram=48M omapfb.vram=0:24M" % append_line

        # do variable substitution on the append line
        # promote all of the autoinstall_meta variables
        if "autoinstall_meta" in blended:
            blended.update(blended["autoinstall_meta"])
        append_line = self.templar.render(append_line, utils.flatten(blended), None)

        # For now console=ttySx,BAUDRATE are only set for systems
        # This could get enhanced for profile/distro via utils.blender (inheritance)
        # This also is architecture specific. E.g: Some ARM consoles need: console=ttyAMAx,BAUDRATE
        # I guess we need a serial_kernel_dev = param, that can be set to "ttyAMA" if needed.
        if system:
            if (system.serial_device is not None) or (system.serial_baud_rate is not None):
                if system.serial_device:
                    serial_device = system.serial_device
                else:
                    serial_device = 0
                if system.serial_baud_rate:
                    serial_baud_rate = system.serial_baud_rate
                else:
                    serial_baud_rate = 115200

                append_line = "%s console=ttyS%s,%s" % (append_line, serial_device, serial_baud_rate)

        # FIXME - the append_line length limit is architecture specific
        if len(append_line) >= 1023:
            self.logger.warning("warning: kernel option length exceeds 1023")

        return append_line