Пример #1
0
def setup_sparc_client(image_path, mac_address):
    """
    Function to call setup-sparc_client script
    Arguments:
              image_path - directory path to AI image
              mac_address - client MAC address (to be interpreted by
                            MACAddress class)
    Returns: Nothing
    Raises: SystemExit if command fails
    """
    # create a DHCP client-identifier (01 + MAC ADDRESS)
    client_id = "01" + mac_address
    # get the host IP address (this only gets the IP of the host's
    # nodename not all interface IP addresses)
    server_ip = socket.gethostbyname(socket.gethostname())
    http_port = "5555"
    cgibin_wanboot_cgi = "/cgi-bin/wanboot-cgi"
    cmd = {
        "cmd":
        ["/usr/lib/installadm/setup-sparc", "client", client_id, image_path]
    }
    try:
        cmd = com.run_cmd(cmd)
    except SystemExit, e:
        raise SystemExit(_("Unable to setup SPARC client: %s\n") % e)
Пример #2
0
def kill_processes(service):
    '''
    Kill dns-sd, AI webserver and Apache image-server processes.
    Returns None and prints errors catching exceptions raised
    '''

    procsToKill = [{
        "proc":
        "dns-sd",
        "searchStr":
        # match a dns-sd with the serviceName and "_" from service type
        # (which is "_OSInstall")
        # Note: this means the maximum serviceName we can match on is 59
        # characters long
        "/usr/bin/dns-sd -R " + service.serviceName + " _"
    }]

    try:
        procsToKill.append({
            "proc":
            "ai-webserver",
            "searchStr":
            "/usr/bin/python2.7 " + "/usr/lib/installadm/webserver -p " +
            # port number (as txt_record is
            # serverName:port (we want the second
            # item from the split which is the port
            # number)
            service['txt_record'].split(':')[1]
        })
    # if txt_record key not found error and continue
    except KeyError:
        sys.stderr.write(_("Unable to kill ai-webserver process.\n"))

    ps = {}
    try:
        ps = com.run_cmd({"cmd": ["/usr/bin/ps", "-efo", "pid args"]})
    # if run_cmd errors out we should return
    except SystemExit, e:
        sys.stderr.write(str(e) + "\n")
        return
Пример #3
0
def setup_tftp_links(service_name, image_path, mac_address, boot_args="null"):
    """
    Function to call into setup_tftp_links script
    Arguments:
              service_name - the AI service to add the client to
              image_path - directory path to AI image
              mac_address - client MAC address (to be interpreted by
                            MACAddress class)
              boot_args - list of boot arguments to pass via GRUB
    Returns: Nothing
    Raises: SystemExit if command fails
    """
    # create a DHCP client-identifier (01 + MAC ADDRESS)
    client_id = "01" + mac_address
    cmd = {
        "cmd": [
            "/usr/lib/installadm/setup-tftp-links", "client", service_name,
            "unknown", image_path, client_id, boot_args
        ]
    }
    try:
        cmd = com.run_cmd(cmd)
    except SystemExit, e:
        raise SystemExit(_("Unable to setup x86 client: %s\n") % e)
Пример #4
0
def setup_dhcp(mac_address, arch):
    """
    Function to call setup-dhcp script
    Arguments:
              mac_address - client MAC address (to be interpreted by
                            MACAddress class)
              arch - architecture to setup for ("SPARC" or "X86")
    Returns: Nothing
    Raises: SystemExit if command fails,
            AssertionError if an unrecognized architecture is passed in
            (recognized are SPARC and X86)
    """
    # normalize architecutre case
    arch = arch.upper()
    # create a DHCP client-identifier (01 + MAC ADDRESS)
    client_id = "01" + mac_address

    # get the host IP address (this only gets the IP of the host's nodename not
    # all interface IP addresses)
    server_ip = socket.gethostbyname(socket.gethostname())
    # setup the boot file correctly per architecture
    if arch == "SPARC":
        http_port = "5555"
        cgibin_wanboot_cgi = "/cgi-bin/wanboot-cgi"
        boot_file = "http://" + server_ip + ":" + http_port + cgibin_wanboot_cgi
    elif arch == "X86":
        boot_file = client_id
    else:
        raise AssertionError("Architecture unrecognized!")

    # run setup-dhcp shell script
    # architecture needs be lower case for setup-dhcp.sh
    cmd = {
        "cmd": [
            "/usr/lib/installadm/setup-dhcp", "client",
            arch.lower(), server_ip, client_id, boot_file
        ]
    }
    try:
        cmd = com.run_cmd(cmd)
    except SystemExit:
        # Print nothing if setup-dhcp returns non-zero. setup-dhcp takes care
        # of providing instructions for the user in that case.
        print cmd["out"]
        # print script's std. err. output as the SystemExit exception message
        # if there was any (otherwise, just ignore this as setup-dhcp returns 1
        # for manual setup needed)
        if cmd["err"]:
            exe = SystemExit(cmd["err"])
            # pass the return code
            exe.code = cmd["subproc"].returncode
            # return the exception
            raise exe
        else:
            return

        print cmd["out"]

        print _("Enabled network boot by adding a macro named %s\n"
                "to DHCP server with:\n"
                "  Boot server IP     (BootSrvA) : %s\n"
                "  Boot file          (BootFile) : %s\n") % \
              (client_id, server_ip, boot_file)
Пример #5
0
    def removeTFTPBootFiles(service):
        '''
        Handle file removal in /tftpboot by building a list of files to remove:
        First, adds pxegrub.<directory pointed to by /tftpboot/<service
         name> i.e. pxegrub.I86PC.Solaris-1
        Unmounts directory which is boot archive (will be something like
         I86PC.Solaris-4) and removes /etc/vfstab entry for mount point

        Calls /tftpboot/rm.<service name> which should remove:
            /tftpboot/<service name>
            /tftpboot/menu.lst.<service name>
            (if the above aren't removed by the rm.<service name> script they
             are added to the remove list)
        Adds /tftpboot/rm.<service name>
        
        Returns: If unable to find tftp root - None
                 Success - A list of file paths to remove
        '''
        # store files to pass back for removal
        files = []

        # check that we have a valid tftpboot directory and set baseDir to it
        baseDir = com.find_TFTP_root()
        if not baseDir:
            sys.stderr.write(
                _("Unable to remove the grub executable, boot " +
                  "archive, or menu.lst file\nwithout a valid " +
                  "tftp root directory.\n"))
            return

        # if we have a boot_file use it instead of serviceName for paths
        try:
            service_name = service['boot_file']
        except KeyError:
            service_name = service.serviceName

        # see if the directory pointed to by /tftpboot/<service name> exists
        curPath = os.path.join(baseDir, service_name)
        if (not os.path.exists(curPath)):
            sys.stderr.write(
                _("The grub executable %s " + "for service %s is missing.\n") %
                (curPath, service.serviceName))
        else:
            # find the target of the sym link for /tftpboot/<service name>
            pxe_grub = os.readlink(curPath)
            # see if the target still exists
            if (os.path.exists(os.path.join(baseDir, pxe_grub))):
                # get a list of all symlinks in /tftpboot, and then resolve
                # their target path

                # get all files in baseDir
                baseDirFiles = [
                    os.path.join(baseDir, f) for f in os.listdir(baseDir)
                ]
                # get all links in baseDir
                links = filter(os.path.islink, baseDirFiles)
                # get all paths in baseDir
                paths = [os.readlink(l) for l in links]
                # there's only one symlink pointing to our boot archive,
                # it is fine to remove it
                if (paths.count(pxe_grub) == 1):
                    pxe_grub = os.path.join(baseDir, pxe_grub)
                    files.append(pxe_grub)

        # Use GRUB menu to check for boot_archive, see that it exists
        grub_menu_prefix = "menu.lst."
        grub_menu = grub_menu_prefix + service_name
        if not os.path.exists(os.path.join(baseDir, grub_menu)):
            sys.stderr.write(
                _("Unable to find GRUB menu at %s, and thus " +
                  "unable to find boot archive.\n") % grub_menu)
        else:
            # check the menu.lst file for the boot archive(s) in use
            menuLst = com.GrubMenu(file_name=os.path.join(baseDir, grub_menu))

            # iterate over both module and module$ of the service's grub menus
            # looking for boot_archive
            for boot_archive in [
                    menuLst[entry].get('module')
                    or menuLst[entry].get('module$')
                    for entry in menuLst.entries
            ]:

                # iterate over all grub menus to see if this boot_archive
                # is in use by another service
                inUse = []
                # build a list of grub menus from baseDir
                menus = [
                    filename for filename in os.listdir(baseDir) if
                    # only select files which start with grub menu prefix
                    filename.startswith(grub_menu_prefix) and
                    # do not select the menu file the service uses
                    filename != os.path.basename(menuLst.file_obj.file_name)
                ]
                # iterate over all menus except the current service's
                for menuName in menus:
                    otherMenu = com.GrubMenu(
                        file_name=os.path.join(baseDir, menuName))

                    # iterate over all entries looking for boot_archive
                    if boot_archive in [
                            otherMenu[entry].get('module')
                            or otherMenu[entry].get("module$")
                            for entry in otherMenu.entries
                    ]:
                        # boot_archive was in use add service/client name
                        inUse.append(menuName.lstrip(grub_menu_prefix))

                # if this boot_archive is in use, skip it (but explain why)
                if inUse:
                    sys.stderr.write(
                        _("Not removing boot archive %s. " +
                          "Boot archive is in-use by " + "service/clients:\n")
                        % boot_archive)
                    for obj in inUse:
                        print obj
                    continue

                # boot_archive will be relative to /tftpboot so will appear to
                # be an absolute path (i.e. will have a leading slash) and will
                # point to the RAM disk
                boot_archive = baseDir + "/" + \
                               boot_archive.split(os.path.sep, 2)[1]

                # see if it is a mount point
                # os.path.ismount() doesn't work for a lofs FS so use
                # /etc/mnttab instead
                if boot_archive in com.MNTTab().fields.MOUNT_POINT:
                    # unmount filesystem
                    try:
                        com.run_cmd(
                            {"cmd": ["/usr/sbin/umount", boot_archive]})
                    # if run_cmd errors out we should continue
                    except SystemExit, e:
                        sys.stderr.write(str(e) + "\n")

                # boot archive directory not a mountpoint
                else:
                    sys.stderr.write(
                        _("Boot archive %s for service is " +
                          "not a mountpoint.\n") %
                        os.path.join(baseDir, boot_archive))
                removeBootArchiveFromVFSTab(boot_archive)
                files.append(boot_archive)
Пример #6
0
                        os.path.join(baseDir, boot_archive))
                removeBootArchiveFromVFSTab(boot_archive)
                files.append(boot_archive)

        # call /tftpboot/rm.<service name> which should remove:
        # /tftpboot/menu.lst.<service name>
        # /tftpboot/<service name>
        rmCMD = os.path.join(baseDir, "rm." + service_name)
        # ensure /tftpboot/rm.<service name> exists
        if os.path.exists(rmCMD):
            try:
                # make the rm script rwxr--r--
                os.chmod(
                    rmCMD, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRWXU
                    | stat.S_IRGRP | stat.S_IROTH)
                com.run_cmd({"cmd": [rmCMD]})

            # if run_cmd errors out we should continue
            except (IOError, SystemExit, OSError), e:
                sys.stderr.write(str(e) + "\n")

        # check that files which should have been removed, were and if not
        # append them for removal from this script:

        # check remove script (/tftpboot/rm.<service name>) removed itself
        if os.path.exists(rmCMD):
            files.append(rmCMD)

        # check GRUB menu (/tftpboot/menu.lst.<service name>)
        if os.path.exists(os.path.join(baseDir, grub_menu)):
            files.append(os.path.join(baseDir, grub_menu))