Пример #1
0
    def __init__(self, collection_mgr, verbose=True, dhcp=None, dns=None, logger=None, tftpd=None):
        """
        Constructor
        """
        self.logger = logger
        if logger is None:
            self.logger = clogger.Logger()

        self.verbose = verbose
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr, self.logger)
        self.tftpgen = tftpgen.TFTPGen(collection_mgr, self.logger)
        self.dns = dns
        self.dhcp = dhcp
        self.tftpd = tftpd
        self.bootloc = self.settings.tftpboot_location
        self.tftpgen.verbose = verbose
        self.dns.verbose = verbose
        self.dhcp.verbose = verbose

        self.pxelinux_dir = os.path.join(self.bootloc, "pxelinux.cfg")
        self.grub_dir = os.path.join(self.bootloc, "grub")
        self.images_dir = os.path.join(self.bootloc, "images")
        self.yaboot_bin_dir = os.path.join(self.bootloc, "ppc")
        self.yaboot_cfg_dir = os.path.join(self.bootloc, "etc")
        self.rendered_dir = os.path.join(self.settings.webdir, "rendered")
Пример #2
0
def run(api, args, logger):
    settings = api.settings()

    for distro in api.distros():
        # collapse the object down to a rendered datastructure
        # the second argument set to false means we don't collapse hashes/arrays into a flat string
        target = utils.blender(api, False, distro)

        # Create metadata for the templar function
        # Right now, just using img_path, but adding more
        # cobbler variables here would probably be good
        metadata = {}
        metadata["img_path"] = os.path.join("/tftpboot/images", distro.name)

        # Create the templar instance
        templater = templar.Templar()

        # Loop through the hash of fetchable files,
        # executing a cp for each one
        for file in target["fetchable_files"].keys():
            file_dst = templater.render(file, metadata, None)
            try:
                shutil.copyfile(target["fetchable_files"][file], file_dst)
                api.log(
                    "copied file %s to %s for %s" %
                    (target["fetchable_files"][file], file_dst, distro.name))
            except:
                logger.error(
                    "failed to copy file %s to %s for %s" %
                    (target["fetchable_files"][file], file_dst, distro.name))
                return 1

    return 0
Пример #3
0
    def __init__(self, config, logger):
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.config = config
        self.systems = config.systems()
        self.templar = templar.Templar(config)
Пример #4
0
    def __init__(self, config):
        """
        This class can manage a New-DJBDNS server.

        :param config: Currently an usused parameter.
        """

        self.config = config
        self.systems = config.systems()
        self.templar = templar.Templar(config)
Пример #5
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.collection_mgr = collection_mgr
        self.templar = templar.Templar(collection_mgr)
Пример #6
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.collection_mgr = collection_mgr
        self.templar = templar.Templar(collection_mgr)
        self.settings_file = "/etc/xinetd.d/tftp"
Пример #7
0
 def __init__(self, collection_mgr):
     """
     Constructor
     """
     self.collection_mgr = collection_mgr
     self.api = collection_mgr.api
     self.distros = collection_mgr.distros()
     self.profiles = collection_mgr.profiles()
     self.systems = collection_mgr.systems()
     self.settings = collection_mgr.settings()
     self.repos = collection_mgr.repos()
     self.templar = templar.Templar(collection_mgr)
Пример #8
0
    def __init__(self, collection_mgr):
        """
        Constructor

        :param collection_mgr: The collection manager to resolve all information with.
        """
        self.logger = logging.getLogger()

        self.collection_mgr = collection_mgr
        self.templar = templar.Templar(collection_mgr)
        self.tftpgen = tftpgen.TFTPGen(collection_mgr)
        self.systems = collection_mgr.systems()
        self.bootloc = collection_mgr.settings().tftpboot_location
Пример #9
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.collection_mgr = collection_mgr
        self.templar = templar.Templar(collection_mgr)
        self.settings_file = "/etc/xinetd.d/tftp"
        self.tftpgen = tftpgen.TFTPGen(collection_mgr, self.logger)
        self.systems = collection_mgr.systems()
        self.bootloc = utils.tftpboot_location()
Пример #10
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor

        :param collection_mgr: The instance who holds all the information from Cobbler.
        :param logger: The logger to audit all actions with.
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.collection_mgr = collection_mgr
        self.bootloc = collection_mgr.settings().tftpboot_location
        self.templar = templar.Templar(collection_mgr)
Пример #11
0
    def __init__(self, collection_mgr):
        """
        Constructor

        :param collection_mgr: The main collection manager instance which is used by the current running server.
        """
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
Пример #12
0
    def __init__(self, config, logger):
        """
        This class can manage a New-DJBDNS server.

        :param config: Currently an usused parameter.
        :param logger: The logger to audit the actions with.
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.config = config
        self.systems = config.systems()
        self.templar = templar.Templar(config)
Пример #13
0
 def __init__(self, collection_mgr, logger):
     """
     Constructor
     """
     self.logger = logger
     self.collection_mgr = collection_mgr
     self.api = collection_mgr.api
     self.distros = collection_mgr.distros()
     self.profiles = collection_mgr.profiles()
     self.systems = collection_mgr.systems()
     self.settings = collection_mgr.settings()
     self.repos = collection_mgr.repos()
     self.templar = templar.Templar(collection_mgr)
     self.settings_file = utils.dhcpconf_location(self.api)
Пример #14
0
 def __init__(self, collection_mgr, logger):
     """
     Constructor
     """
     self.collection_mgr = collection_mgr
     self.logger = logger
     self.api = collection_mgr.api
     self.distros = collection_mgr.distros()
     self.profiles = collection_mgr.profiles()
     self.systems = collection_mgr.systems()
     self.settings = collection_mgr.settings()
     self.repos = collection_mgr.repos()
     self.images = collection_mgr.images()
     self.templar = templar.Templar(collection_mgr)
     self.bootloc = self.settings.tftpboot_location
Пример #15
0
    def __init__(self, collection_mgr):
        """
        Constructor

        :param collection_mgr: The collection manager to resolve all information with.
        """
        self.logger = logging.getLogger()
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
Пример #16
0
    def __init__(self, collection_mgr):
        """
        Constructor

        :param collection_mgr: The collection manager instance which is used for this object. Normally there is only one
                               instance of the collection manager.
        """
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
Пример #17
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor

        :param collection_mgr: The collection manager to resolve all information with.
        :param logger: The logger to audit all actions with.
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.collection_mgr = collection_mgr
        self.templar = templar.Templar(collection_mgr)
        self.tftpgen = tftpgen.TFTPGen(collection_mgr, self.logger)
        self.systems = collection_mgr.systems()
        self.bootloc = collection_mgr.settings().tftpboot_location
    def __init__(self, collection_mgr, logger):
        """
        Constructor
        """
        self.logger = logger
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)

        self.signature = None
        self.found_repos = {}
Пример #19
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor

        :param collection_mgr: The collection manager to resolve all information with.
        :param logger: The logger to audit all actions with.
        """
        self.logger = logger
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
        self.settings_file = utils.dhcpconf_location()
Пример #20
0
    def __init__(self,
                 collection_mgr,
                 verbose=True,
                 dhcp=None,
                 dns=None,
                 logger=None,
                 tftpd=None):
        """
        Constructor

        :param collection_mgr: The collection manager instance which holds all information about cobbler.
        :param verbose: Whether to log the actions performed in this module verbose or not.
        :param dhcp: The DHCP manager which can update the DHCP config.
        :param dns: The DNS manager which can update the DNS config.
        :param logger: The logger to audit all action with.
        :param tftpd: The TFTP manager which can update the TFTP config.
        """
        self.logger = logger
        if logger is None:
            self.logger = clogger.Logger()

        self.verbose = verbose
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr, self.logger)
        self.tftpgen = tftpgen.TFTPGen(collection_mgr, self.logger)
        self.dns = dns
        self.dhcp = dhcp
        self.tftpd = tftpd
        self.bootloc = self.settings.tftpboot_location
        self.tftpgen.verbose = verbose
        self.dns.verbose = verbose
        self.dhcp.verbose = verbose

        self.pxelinux_dir = os.path.join(self.bootloc, "pxelinux.cfg")
        self.grub_dir = os.path.join(self.bootloc, "grub")
        self.images_dir = os.path.join(self.bootloc, "images")
        self.yaboot_bin_dir = os.path.join(self.bootloc, "ppc")
        self.yaboot_cfg_dir = os.path.join(self.bootloc, "etc")
        self.ipxe_dir = os.path.join(self.bootloc, "ipxe")
        self.rendered_dir = os.path.join(self.settings.webdir, "rendered")
Пример #21
0
    def __init__(self, collection_mgr, logger, dhcp=None):
        """
        Constructor

        :param collection_mgr: The collection manager to resolve all information with.
        :param logger: The logger to audit all actions with.
        :param dhcp: This parameter is unused currently.
        """
        self.logger = logger
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
Пример #22
0
    def __init__(self, collection_mgr):
        """
        Constructor to create a default BindManager object.

        :param collection_mgr: The collection manager to resolve all information with.
        """
        self.logger = logging.getLogger()

        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
        self.settings_file = utils.namedconf_location()
        self.zonefile_base = utils.zonefile_base()
Пример #23
0
    def __init__(self, collection_mgr):
        """
        Main constructor for our class.

        :param collection_mgr: This is the collection manager which has every information in Cobbler available.
        """
        self.logger = logging.getLogger()
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)

        self.signature = None
        self.found_repos = {}
Пример #24
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor
        """
        self.logger = logger
        if self.logger is None:
            self.logger = clogger.Logger()

        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
        self.settings_file = utils.namedconf_location(self.api)
        self.zonefile_base = utils.zonefile_base(self.api)
Пример #25
0
    def write_boot_files_distro(self, distro):
        # Collapse the object down to a rendered datastructure.
        # The second argument set to false means we don't collapse dicts/arrays into a flat string.
        target = utils.blender(self.api, False, distro)

        # Create metadata for the templar function.
        # Right now, just using local_img_path, but adding more Cobbler variables here would probably be good.
        metadata = {}
        metadata["local_img_path"] = os.path.join(self.bootloc, "images",
                                                  distro.name)
        metadata["web_img_path"] = os.path.join(self.webdir, "distro_mirror",
                                                distro.name)
        # Create the templar instance.  Used to template the target directory
        templater = templar.Templar(self.collection_mgr)

        # Loop through the dict of boot files, executing a cp for each one
        self.logger.info("processing boot_files for distro: %s" % distro.name)
        for boot_file in list(target["boot_files"].keys()):
            rendered_target_file = templater.render(boot_file, metadata, None)
            rendered_source_file = templater.render(
                target["boot_files"][boot_file], metadata, None)
            try:
                for file in glob.glob(rendered_source_file):
                    if file == rendered_source_file:
                        # this wasn't really a glob, so just copy it as is
                        filedst = rendered_target_file
                    else:
                        # this was a glob, so figure out what the destination file path/name should be
                        tgt_path, tgt_file = os.path.split(file)
                        rnd_path, rnd_file = os.path.split(
                            rendered_target_file)
                        filedst = os.path.join(rnd_path, tgt_file)

                        if not os.path.isdir(rnd_path):
                            utils.mkdir(rnd_path)
                    if not os.path.isfile(filedst):
                        shutil.copyfile(file, filedst)
                    self.collection_mgr.api.log("copied file %s to %s for %s" %
                                                (file, filedst, distro.name))
            except:
                self.logger.error("failed to copy file %s to %s for %s", file,
                                  filedst, distro.name)

        return 0
Пример #26
0
    def __init__(self,
                 collection_mgr,
                 verbose: bool = True,
                 dhcp=None,
                 dns=None,
                 tftpd=None):
        """
        Constructor

        :param collection_mgr: The collection manager instance which holds all information about cobbler.
        :param verbose: Whether to log the actions performed in this module verbose or not.
        :param dhcp: The DHCP manager which can update the DHCP config.
        :param dns: The DNS manager which can update the DNS config.
        :param tftpd: The TFTP manager which can update the TFTP config.
        """
        self.logger = logging.getLogger()

        self.verbose = verbose
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.images = collection_mgr.images()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)
        self.tftpgen = tftpgen.TFTPGen(collection_mgr)
        self.dns = dns
        self.dhcp = dhcp
        self.tftpd = tftpd
        self.bootloc = self.settings.tftpboot_location

        self.pxelinux_dir = os.path.join(self.bootloc, "pxelinux.cfg")
        self.grub_dir = os.path.join(self.bootloc, "grub")
        self.images_dir = os.path.join(self.bootloc, "images")
        self.ipxe_dir = os.path.join(self.bootloc, "ipxe")
        self.rendered_dir = os.path.join(self.settings.webdir, "rendered")
        self.links = os.path.join(self.settings.webdir, "links")
        self.distromirror_config = os.path.join(self.settings.webdir,
                                                "distro_mirror/config")
        # FIXME: See https://github.com/cobbler/cobbler/issues/2453
        # Move __create_tftpboot_dirs() outside of sync.py.
        self.__create_tftpboot_dirs()
Пример #27
0
    def __init__(self, collection_mgr, logger):
        """
        Constructor

        :param collection_mgr: This is the collection manager which has every information in Cobbler available.
        :param logger: This is the logger to audit all actions with.
        """
        self.logger = logger
        self.collection_mgr = collection_mgr
        self.api = collection_mgr.api
        self.distros = collection_mgr.distros()
        self.profiles = collection_mgr.profiles()
        self.systems = collection_mgr.systems()
        self.settings = collection_mgr.settings()
        self.repos = collection_mgr.repos()
        self.templar = templar.Templar(collection_mgr)

        self.signature = None
        self.found_repos = {}
Пример #28
0
def run(api, args, logger):
    # FIXME: make everything use the logger

    settings = api.settings()

    # go no further if this feature is turned off
    if not str(settings.build_reporting_enabled).lower() in [
            "1", "yes", "y", "true"
    ]:
        return 0

    objtype = args[0]  # "target" or "profile"
    name = args[1]  # name of target or profile
    boot_ip = args[2]  # ip or "?"

    if objtype == "system":
        target = api.find_system(name)
    else:
        target = api.find_profile(name)

    # collapse the object down to a rendered datastructure
    target = utils.blender(api, False, target)

    if target == {}:
        raise CX("failure looking up target")

    to_addr = settings.build_reporting_email
    if to_addr == "":
        return 0

    # add the ability to specify an MTA for servers that don't run their own
    smtp_server = settings.build_reporting_smtp_server
    if smtp_server == "":
        smtp_server = "localhost"

    # use a custom from address or fall back to a reasonable default
    from_addr = settings.build_reporting_sender
    if from_addr == "":
        from_addr = "cobbler@%s" % settings.server

    subject = settings.build_reporting_subject
    if subject == "":
        subject = '[Cobbler] install complete '

    to_addr = ", ".join(to_addr)
    metadata = {
        "from_addr": from_addr,
        "to_addr": to_addr,
        "subject": subject,
        "boot_ip": boot_ip
    }
    metadata.update(target)

    input_template = open("/etc/cobbler/reporting/build_report_email.template")
    input_data = input_template.read()
    input_template.close()

    message = templar.Templar().render(input_data, metadata, None)
    # for debug, call
    # print message

    # Send the mail
    # FIXME: on error, return non-zero
    server_handle = smtplib.SMTP(smtp_server)
    server_handle.sendmail(from_addr, to_addr, message)
    server_handle.quit()

    return 0
Пример #29
0
def run(api, args):
    settings = api.settings()
    if not settings.windows_enabled:
        return 0
    if not HAS_HIVEX:
        logger.info(
            "python3-hivex or python3-pefile not found. If you need Automatic Windows Installation support, "
            "please install.")
        return 0

    profiles = api.profiles()
    systems = api.systems()
    templ = templar.Templar(api._collection_mgr)
    tgen = tftpgen.TFTPGen(api._collection_mgr)

    with open(
            os.path.join(settings.windows_template_dir,
                         post_inst_cmd_template_name)) as template_win:
        post_tmpl_data = template_win.read()

    with open(
            os.path.join(settings.windows_template_dir,
                         answerfile_template_name)) as template_win:
        tmpl_data = template_win.read()

    with open(
            os.path.join(settings.windows_template_dir,
                         startnet_template_name)) as template_start:
        tmplstart_data = template_start.read()

    def gen_win_files(distro, meta):
        (kernel_path, kernel_name) = os.path.split(distro.kernel)
        distro_path = utils.find_distro_path(settings, distro)
        distro_dir = wim_file_name = os.path.join(settings.tftpboot_location,
                                                  "images", distro.name)
        web_dir = os.path.join(settings.webdir, "images", distro.name)
        is_winpe = "winpe" in meta and meta['winpe'] != ""
        is_bcd = "bcd" in meta and meta['bcd'] != ""

        if "kernel" in meta:
            kernel_name = meta["kernel"]

        kernel_name = os.path.basename(kernel_name)
        is_wimboot = "wimboot" in kernel_name

        if is_wimboot:
            distro_path = os.path.join(settings.webdir, "distro_mirror",
                                       distro.name)
            kernel_path = os.path.join(distro_path, "Boot")

            if "kernel" in meta and "wimboot" not in distro.kernel:
                tgen.copy_single_distro_file(
                    os.path.join(settings.tftpboot_location, kernel_name),
                    distro_dir, False)
                tgen.copy_single_distro_file(
                    os.path.join(distro_dir, kernel_name), web_dir, True)

        if "post_install_script" in meta:
            post_install_dir = distro_path

            if distro.os_version not in ("XP", "2003"):
                post_install_dir = os.path.join(post_install_dir, "sources")

            post_install_dir = os.path.join(post_install_dir, "$OEM$", "$1")

            if not os.path.exists(post_install_dir):
                utils.mkdir(post_install_dir)

            data = templ.render(post_tmpl_data, meta, None)
            post_install_script = os.path.join(post_install_dir,
                                               meta["post_install_script"])
            logger.info('Build post install script: ' + post_install_script)
            with open(post_install_script, "w+") as pi_file:
                pi_file.write(data)

        if "answerfile" in meta:
            data = templ.render(tmpl_data, meta, None)
            answerfile_name = os.path.join(distro_dir, meta["answerfile"])
            logger.info('Build answer file: ' + answerfile_name)
            with open(answerfile_name, "w+") as answerfile:
                answerfile.write(data)
            tgen.copy_single_distro_file(answerfile_name, distro_path, False)
            tgen.copy_single_distro_file(answerfile_name, web_dir, True)

        if "kernel" in meta and "bootmgr" in meta:
            wk_file_name = os.path.join(distro_dir, kernel_name)
            wl_file_name = os.path.join(distro_dir, meta["bootmgr"])
            tl_file_name = os.path.join(kernel_path, "bootmgr.exe")

            if distro.os_version in ("XP", "2003") and not is_winpe:
                tl_file_name = os.path.join(kernel_path, "setupldr.exe")

                if len(meta["bootmgr"]) != 5:
                    logger.error(
                        "The loader name should be EXACTLY 5 character")
                    return 1

                pat1 = re.compile(br'NTLDR', re.IGNORECASE)
                pat2 = re.compile(br'winnt\.sif', re.IGNORECASE)
                with open(tl_file_name, 'rb') as file:
                    out = data = file.read()

                if "answerfile" in meta:
                    if len(meta["answerfile"]) != 9:
                        logger.error(
                            "The response file name should be EXACTLY 9 character"
                        )
                        return 1

                    out = pat2.sub(bytes(meta["answerfile"], 'utf-8'), data)
            else:
                if len(meta["bootmgr"]) != 11:
                    logger.error(
                        "The Boot manager file name should be EXACTLY 11 character"
                    )
                    return 1

                bcd_name = "bcd"
                if is_bcd:
                    bcd_name = meta["bcd"]
                    if len(bcd_name) != 3:
                        logger.error(
                            "The BCD file name should be EXACTLY 3 character")
                        return 1

                if not os.path.isfile(tl_file_name):
                    logger.error("File not found: %s" % tl_file_name)
                    return 1

                pat1 = re.compile(br'bootmgr\.exe', re.IGNORECASE)
                pat2 = re.compile(br'(\\.B.o.o.t.\\.)(B)(.)(C)(.)(D)',
                                  re.IGNORECASE)

                bcd_name = bytes(
                    "\\g<1>" + bcd_name[0] + "\\g<3>" + bcd_name[1] +
                    "\\g<5>" + bcd_name[2], 'utf-8')
                with open(tl_file_name, 'rb') as file:
                    out = file.read()

                if not is_wimboot:
                    logger.info('Patching build Loader: %s' % wl_file_name)
                    out = pat2.sub(bcd_name, out)

            if tl_file_name != wl_file_name:
                logger.info('Build Loader: %s from %s' %
                            (wl_file_name, tl_file_name))
                with open(wl_file_name, 'wb+') as file:
                    file.write(out)
                tgen.copy_single_distro_file(wl_file_name, web_dir, True)

            if not is_wimboot:
                if distro.os_version not in ("XP", "2003") or is_winpe:
                    pe = pefile.PE(wl_file_name, fast_load=True)
                    pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
                    pe.write(filename=wl_file_name)

                with open(distro.kernel, 'rb') as file:
                    data = file.read()
                out = pat1.sub(bytes(meta["bootmgr"], 'utf-8'), data)

                if wk_file_name != distro.kernel:
                    logger.info("Build PXEBoot: %s from %s" %
                                (wk_file_name, distro.kernel))
                    with open(wk_file_name, 'wb+') as file:
                        file.write(out)
                    tgen.copy_single_distro_file(wk_file_name, web_dir, True)

        if is_bcd:
            obcd_file_name = os.path.join(kernel_path, "bcd")
            bcd_file_name = os.path.join(distro_dir, meta["bcd"])
            wim_file_name = 'winpe.wim'

            if not os.path.isfile(obcd_file_name):
                logger.error("File not found: %s" % obcd_file_name)
                return 1

            if is_winpe:
                wim_file_name = meta["winpe"]

            if is_wimboot:
                wim_file_name = '\\Boot\\' + wim_file_name
                sdi_file_name = '\\Boot\\' + 'boot.sdi'
            else:
                wim_file_name = os.path.join("/images", distro.name,
                                             wim_file_name)
                sdi_file_name = os.path.join("/images", distro.name,
                                             os.path.basename(distro.initrd))

            logger.info('Build BCD: %s from %s for %s' %
                        (bcd_file_name, obcd_file_name, wim_file_name))
            bcdedit(obcd_file_name, bcd_file_name, wim_file_name,
                    sdi_file_name)
            tgen.copy_single_distro_file(bcd_file_name, web_dir, True)

        if is_winpe:
            ps_file_name = os.path.join(distro_dir, meta["winpe"])
            wim_pl_name = os.path.join(kernel_path, "winpe.wim")

            cmd = ["/usr/bin/cp", "--reflink=auto", wim_pl_name, ps_file_name]
            utils.subprocess_call(logger, cmd, shell=False)
            tgen.copy_single_distro_file(ps_file_name, web_dir, True)

            if os.path.exists(wimupdate):
                data = templ.render(tmplstart_data, meta, None)
                pi_file = tempfile.NamedTemporaryFile()
                pi_file.write(bytes(data, 'utf-8'))
                pi_file.flush()
                cmd = [
                    wimupdate, ps_file_name, "--command=add " + pi_file.name +
                    " /Windows/System32/startnet.cmd"
                ]
                utils.subprocess_call(cmd, shell=False)
                pi_file.close()

    for profile in profiles:
        distro = profile.get_conceptual_parent()

        if distro and distro.breed == "windows":
            logger.info('Profile: ' + profile.name)
            meta = utils.blender(api, False, profile)
            autoinstall_meta = meta.get("autoinstall_meta", {})
            meta.update(autoinstall_meta)
            gen_win_files(distro, meta)

    for system in systems:
        profile = system.get_conceptual_parent()
        autoinstall_meta = system.autoinstall_meta

        if not profile or not autoinstall_meta or autoinstall_meta == {}:
            continue

        distro = profile.get_conceptual_parent()

        if distro and distro.breed == "windows":
            logger.info('System: ' + system.name)
            meta = utils.blender(api, False, system)
            gen_win_files(distro, autoinstall_meta)
    return 0
Пример #30
0
def run(api, args):
    if not HAS_HIVEX:
        logger.info("python3-hivex or python3-pefile not found. If you need Automatic Windows Installation support, "
                    "please install.")
        return 0

    distros = api.distros()
    profiles = api.profiles()
    templ = templar.Templar(api._collection_mgr)
    template_win = open(post_inst_cmd_template_name)
    tmpl_data = template_win.read()
    template_win.close()

    for distro in distros:
        if distro.breed == "windows":
            meta = utils.blender(api, False, distro)

            if "post_install" in distro.kernel_options:
                data = templ.render(tmpl_data, meta, None)
                pi_file = open(distro.kernel_options["post_install"], "w+")
                pi_file.write(data)
                pi_file.close()

    template_win = open(sif_template_name)
    tmpl_data = template_win.read()
    template_win.close()

    template_start = open(startnet_template_name)
    tmplstart_data = template_start.read()
    template_start.close()

    logger.info("\nWindows profiles:")

    for profile in profiles:
        distro = profile.get_conceptual_parent()

        if distro.breed == "windows":
            logger.info('Profile: ' + profile.name)
            meta = utils.blender(api, False, profile)
            (distro_path, pxeboot_name) = os.path.split(distro.kernel)

            if "sif" in profile.kernel_options:
                data = templ.render(tmpl_data, meta, None)

                if distro.os_version in ("7", "2008", "8", "2012", "2016", "2019", "10"):
                    sif_file_name = os.path.join(distro_path, 'sources', profile.kernel_options["sif"])
                else:
                    sif_file_name = os.path.join(distro_path, profile.kernel_options["sif"])

                sif_file = open(sif_file_name, "w+")
                sif_file.write(data)
                sif_file.close()
                logger.info('Build answer file: ' + sif_file_name)

            if "pxeboot" in profile.kernel_options and "bootmgr" in profile.kernel_options:
                wk_file_name = os.path.join(distro_path, profile.kernel_options["pxeboot"])
                wl_file_name = os.path.join(distro_path, profile.kernel_options["bootmgr"])
                logger.info("Build PXEBoot: " + wk_file_name)

                if distro.os_version in ("7", "2008", "8", "2012", "2016", "2019", "10"):
                    if len(profile.kernel_options["bootmgr"]) != 11:
                        logger.error("The loader  name should be EXACTLY 11 character")
                        return 1

                    if "bcd" in profile.kernel_options:
                        if len(profile.kernel_options["bcd"]) != 3:
                            logger.error("The BCD name should be EXACTLY 5 character")
                            return 1

                    tl_file_name = os.path.join(distro_path, 'bootmgr.exe')
                    pat1 = re.compile(br'bootmgr\.exe', re.IGNORECASE)
                    pat2 = re.compile(br'(\\.B.o.o.t.\\.)(B)(.)(C)(.)(D)', re.IGNORECASE)
                    bcd_name = 'BCD'

                    if "bcd" in profile.kernel_options:
                        bcd_name = profile.kernel_options["bcd"]

                    bcd_name = bytes("\\g<1>" + bcd_name[0] + "\\g<3>" + bcd_name[1] + "\\g<5>" + bcd_name[2], 'utf-8')
                    data = open(tl_file_name, 'rb').read()
                    out = pat2.sub(bcd_name, data)
                else:
                    if len(profile.kernel_options["bootmgr"]) != 5:
                        logger.error("The loader name should be EXACTLY 5 character")
                        return 1

                    if len(profile.kernel_options["sif"]) != 9:
                        logger.error("The response should be EXACTLY 9 character")
                        return 1

                    tl_file_name = os.path.join(distro_path, 'setupldr.exe')
                    pat1 = re.compile(br'NTLDR', re.IGNORECASE)
                    pat2 = re.compile(br'winnt\.sif', re.IGNORECASE)

                    data = open(tl_file_name, 'rb').read()
                    out = pat2.sub(bytes(profile.kernel_options["sif"], 'utf-8'), data)

                logger.info('Build Loader: ' + wl_file_name)

                if out != data:
                    open(wl_file_name, 'wb+').write(out)

                if distro.os_version in ("7", "2008", "8", "2012", "2016", "2019", "10"):
                    pe = pefile.PE(wl_file_name, fast_load=True)
                    pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
                    pe.write(filename=wl_file_name)

                data = open(distro.kernel, 'rb').read()
                out = pat1.sub(bytes(profile.kernel_options["bootmgr"], 'utf-8'), data)

                if out != data:
                    open(wk_file_name, 'wb+').write(out)

            if "bcd" in profile.kernel_options:
                obcd_file_name = os.path.join(distro_path, 'boot', 'BCD')
                bcd_file_name = os.path.join(distro_path, 'boot', profile.kernel_options["bcd"])
                wim_file_name = 'winpe.wim'

                if "winpe" in profile.kernel_options:
                    wim_file_name = profile.kernel_options["winpe"]

                if distro.boot_loader == "ipxe":
                    wim_file_name = '\\Boot\\' + wim_file_name
                    sdi_file_name = '\\Boot\\' + 'boot.sdi'
                else:
                    wim_file_name = os.path.join('/winos', distro.name, 'boot', wim_file_name)
                    sdi_file_name = os.path.join('/winos', distro.name, 'boot', 'boot.sdi')

                logger.info('Build BCD: ' + bcd_file_name + ' for ' + wim_file_name)
                bcdedit(obcd_file_name, bcd_file_name, wim_file_name, sdi_file_name)

            if "winpe" in profile.kernel_options:
                ps_file_name = os.path.join(distro_path, "boot", profile.kernel_options["winpe"])

                if distro.os_version in ("7", "2008"):
                    wim_pl_name = wim7_template_name
                elif distro.os_version in ("8", "2012", "2016", "2019", "10"):
                    wim_pl_name = wim8_template_name
                else:
                    raise ValueError("You are trying to use an unsupported distro!")

                cmd = "/usr/bin/cp --reflink=auto " + wim_pl_name + " " + ps_file_name
                utils.subprocess_call(cmd, shell=True)

                if os.path.exists(wimupdate):
                    data = templ.render(tmplstart_data, meta, None)
                    pi_file = tempfile.NamedTemporaryFile()
                    pi_file.write(bytes(data, 'utf-8'))
                    pi_file.flush()
                    cmd = wimupdate + ' ' + ps_file_name + ' --command="add ' + pi_file.name
                    cmd += ' /Windows/System32/startnet.cmd"'
                    utils.subprocess_call(cmd, shell=True)
                    pi_file.close()
    return 0