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)
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
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)
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)
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)
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))