def _set_instance(state, wait_for): '''Set the install/server service to a given state, and wait for it to finish transitioning. state - desired state, e.g. 'MAINTENANCE' or 'RESTORE' wait_for - Function will block until the SMF state of the install/server instance is one of the values passed in this list, e.g. ['DISABLED', 'OFFLINE']. List items should be upper case. Raises ServicesError if the transition doesn't complete before MAX_WAIT_TIME seconds pass. ''' libaiscf.AISCF(FMRI=AI_SVC_FMRI).state = state.upper() # Wait a reasonable amount of time to confirm state change. wait_cnt = 0 while libaiscf.AISCF(FMRI=AI_SVC_FMRI).state.upper() not in wait_for: if wait_cnt >= MAX_WAIT_TIME: logging.debug("Wait time exceeded on attempt to move " "installadm SMF service to %s.", state.lower()) raise ServicesError(cw(_("Error: Failed to place %(svc)s in " "%(state)s. See the output of 'svcs " "-xv %(svc)s' for more information.") % {'svc': AI_SVC_FMRI, 'state': state.lower()})) else: time.sleep(1) wait_cnt += 1 logging.log(com.XDEBUG, "Time to set installadm SMF service to '%s' is %i" " seconds", state, wait_cnt)
def test_default_set_get(self): '''Set up service rudiments so default handling can be tested''' try: self.smf_instance = smf.AISCF(FMRI="system/install/server") except KeyError: raise SystemExit( _("Error:\tThe system/install/server SMF " "service is not running.")) # If the service exists, exit. We don't want to romp on it. if self.service_name in self.smf_instance.services.keys(): raise SystemExit( _("Error: The service %s already exists!!!") % self.service_name) service_data = { aismf.PROP_SERVICE_NAME: self.service_name, aismf.PROP_IMAGE_PATH: self.image_path, aismf.PROP_BOOT_FILE: "dummy_boot", aismf.PROP_TXT_RECORD: com.AIWEBSERVER + "=hostname:" + self.dummy_service_dir, aismf.PROP_STATUS: aismf.STATUS_OFF } aismf.create_pg(self.service_name, service_data) manifest_name = "temp_mfest_name_%d" % os.getpid() properties.set_default(self.service_name, manifest_name, properties.SKIP_MANIFEST_CHECK) self.assertEqual(manifest_name, properties.get_default(self.service_name))
def register_all(self, interfaces=None): '''Method: register_all Description: Registers all AI services. This method will loop until the the application is killed. It responds to SIGHUP signals, re-checking all registered services for additions and removals of a service from the AI SMF service. Args interfaces - the interfaces to register the AI services on Returns None Raises SystemError - if the SMF service instance can not be loaded. AIMDNSError - if the Instance keys are not loaded. ''' self._do_lookup = False if self.verbose: print _('Registering all Auto Install services...') # get the AI SMF service instance information try: self.instance = smf.AISCF(FMRI="system/install/server") except SystemError: raise SystemError( _("error: the system does not have the " "system/install/server SMF service")) self.instance_services = config.get_all_service_names() # use interfaces within the class if none are passed if interfaces is None: interfaces = self.interfaces # iterate through each service and register it for servicename in self.instance_services: sdrefs = self._register_a_service(name=servicename, interfaces=interfaces) # save the service reference within the class if sdrefs: if servicename in self.sdrefs: self.sdrefs[servicename].extend(sdrefs) else: self.sdrefs[servicename] = sdrefs signal.signal(signal.SIGHUP, self._signal_hup) self._handle_events()
def get_smf_instance(): ''' Get the instance for the installadm SMF service Args: None Return: smf instance Raises: ServicesError if the installadm SMF service doesn't exist ''' logging.log(com.XDEBUG, '**** START ai_smf_service.get_smf_instance ****') try: smf_instance = libaiscf.AISCF(FMRI=AI_SVC_FMRI) except KeyError: raise ServicesError(_("The system does not have the " "system/install/server SMF service.\n")) return smf_instance
def get_state(): ''' Return the state of the Automated Installer SMF service. This function is roughly analogous to smf_get_state(3SCF) Input: None Return: state - e.g. 'disabled', 'maintenance'... | None if not found Raises: Whatever exceptions AISCF encounters ''' logging.log(com.XDEBUG, '**** START ai_smf_service.get_state ****') try: return libaiscf.AISCF(FMRI=AI_SVC_FMRI).state except SystemError: return None
def parse_options(): ''' Parse and validate options when called as delete-service Args: None Returns: A tuple of an AIservice object representing service to delete and an options object ''' parser = OptionParser(usage=_("usage: %prog [options] install_service")) parser.add_option("-x", "--delete-image", dest="deleteImage", action="store_true", default=False, help=_("remove service image, if " + "not otherwise in use")) (options, args) = parser.parse_args() # check that we got the install service's name passed in if len(args) != 1: parser.print_help() sys.exit(1) serviceName = args[0] # check the system has the AI install SMF service available try: smf_instance = smf.AISCF(FMRI="system/install/server") except KeyError: raise SystemExit( _("Error:\tThe system does not have the " + "system/install/server SMF service")) # check the service exists if not serviceName in smf_instance.services.keys(): raise SystemExit( _("Error:\tThe specified service does not exist: %s") % serviceName) # return the AIservice object return ((smf.AIservice(smf_instance, serviceName)), options)
def remove_DHCP_macro(service): ''' Checks for existence of DHCP macro Checks for and prints warning for clients using DHCP macro Prints command to remove DHCP macro Args: AIservice object Returns: None ''' # if we are handed a Client_Data object instance macro name is just a MAC # address otherwise prepend "dhcp_macro_" if isinstance(service, Client_Data): macro_name = service.serviceName else: # if we have a boot_file use it instead of serviceName for paths try: macro_name = "dhcp_macro_" + service['boot_file'] except KeyError: macro_name = "dhcp_macro_" + service.serviceName # command to remove DHCP macro cmd = ["/usr/sbin/dhtadm", "-D", "-m", macro_name] # ensure we are a DHCP server if not (smf.AISCF(FMRI="network/dhcp-server").state == "online"): print( _("Detected that DHCP is not set up on this machine. To " + "delete the DHCP macro, run the following on your " + "DHCP server:\n%s\n") % " ".join(cmd)) return # if the macro is not configured return try: if (macro_name not in com.DHCPData.macros()['Name']): return except com.DHCPData.DHCPError, e: sys.stderr.write(str(e) + "\n") return
def list_manifests(service): '''Replies to the client with criteria list for a service. The output should be similar to installadm list. Args service - the name of the service being listed Returns None Raises None ''' print 'Content-Type: text/html' # HTML is following print # blank line, end of headers print '<html>' print '<head>' sys.stdout.write('<title>%s %s</title>' % (_('Manifest list for'), service)) print '</head><body>' port = 0 try: smf.AISCF(FMRI="system/install/server") except KeyError: # report the internal error to error_log and requesting client sys.stderr.write( _("error:The system does not have the " "system/install/server SMF service.")) sys.stdout.write( _("error:The system does not have the " "system/install/server SMF service.")) return services = config.get_all_service_names() if not services: # report the error to the requesting client only sys.stdout.write(_('error:no services on this server.\n')) return found = False if config.is_service(service): service_ctrl = AIService(service) found = True # assume new service setup path = service_ctrl.database_path if os.path.exists(path): try: aisql = AIdb.DB(path) aisql.verifyDBStructure() except StandardError as err: # report the internal error to error_log and # requesting client sys.stderr.write( _('error:AI database access ' 'error\n%s\n') % err) sys.stdout.write( _('error:AI database access ' 'error\n%s\n') % err) return # generate the list of criteria for the criteria table header criteria_header = E.TR() for crit in AIdb.getCriteria(aisql.getQueue(), strip=False): criteria_header.append(E.TH(crit)) # generate the manifest rows for the criteria table body names = AIdb.getManNames(aisql.getQueue()) table_body = E.TR() allcrit = AIdb.getCriteria(aisql.getQueue(), strip=False) colspan = str(max(len(list(allcrit)), 1)) for manifest in names: # iterate through each manifest (and instance) for instance in range( 0, AIdb.numInstances(manifest, aisql.getQueue())): table_body.append(E.TR()) # print the manifest name only once (from instance 0) if instance == 0: href = '../' + service + '/' + manifest row = str(AIdb.numInstances(manifest, aisql.getQueue())) table_body.append( E.TD(E.A(manifest, href=href, rowspan=row))) else: table_body.append(E.TD()) crit_pairs = AIdb.getManifestCriteria(manifest, instance, aisql.getQueue(), onlyUsed=True, humanOutput=True) # crit_pairs is an SQLite3 row object which doesn't # support iteritems(), etc. for crit in crit_pairs.keys(): formatted_val = AIdb.formatValue( crit, crit_pairs[crit]) # if we do not get back a valid value ensure a # hyphen is printed (prevents "" from printing) if formatted_val and crit_pairs[crit]: table_body.append( E.TD(formatted_val, align="center")) else: table_body.append( E.TD(lxml.etree.Entity("nbsp"), align="center")) # print the default manifest at the end of the table, # which has the same colspan as the Criteria List label else: href = '../' + service + '/default.xml' table_body.append( E.TR( E.TD(E.A("Default", href=href)), E.TD(lxml.etree.Entity("nbsp"), colspan=colspan, align="center"))) web_page = E.HTML( E.HEAD(E.TITLE(_("OmniOS Automated " "Installation Webserver"))), E.BODY( E.H1( _("Welcome to the OmniOS " "Automated Installation webserver!")), E.P( _("Service '%s' has the following " "manifests available, served to clients " "matching required criteria.") % service), E.TABLE(E.TR(E.TH(_("Manifest"), rowspan="2"), E.TH(_("Criteria List"), colspan=colspan)), criteria_header, table_body, border="1", align="center"), )) print lxml.etree.tostring(web_page, pretty_print=True) # service is not found, provide available services on host if not found: sys.stdout.write(_('Service <i>%s</i> not found. ') % service) sys.stdout.write(_('Available services are:<p><ol><i>')) host = socket.gethostname() for service_name in config.get_all_service_names(): # assume new service setup port = config.get_service_port(service_name) sys.stdout.write( '<a href="http://%s:%d/cgi-bin/' 'cgi_get_manifest.py?version=%s&service=%s">%s</a><br>\n' % (host, port, VERSION, service_name, service_name)) sys.stdout.write('</i></ol>%s' % _('Please select a service ' 'from the above list.')) print '</body></html>'
parser.add_option("-t", dest="image_path", action="store", type="string", help=_("Path to AI image directory for client"), nargs=1) (options, args) = parser.parse_args() # check that we did not get anything unexptected handed in if len(args) != 0 or not (options.mac_address and options.service_name): parser.print_help() sys.exit(1) # check the system has the AI install SMF service available try: smf_instance = smf.AISCF(FMRI="system/install/server") except KeyError: parser.error( _("The system does not have the " "system/install/server SMF service.\n")) # check the service exists if options.service_name not in smf_instance.services.keys(): parser.error( _("The specified service does not exist: %s\n") % options.service_name) # store AIservice object in options.service options.service = smf.AIservice(smf_instance, options.service_name) # if image_path not specified, set it to the SMF service's image_path
def register(self, servicename=None, port=0, interfaces=None, comments=None): '''Method: register Description: Registers an ad hoc service. This method will loop until the the application is killed. Args servicename - the name of the ad hoc service port - the port to use for the ad hoc service interfaces - the interfaces to register the ad hoc service on comments - the service comments for the ad hoc service Returns None Raises SystemError - if the SMF service instance can not be loaded. AImDNSError - if unable to register the service OR if no servicename is present. ''' self._do_lookup = False if servicename is not None: self.servicename = servicename if self.servicename is None: raise ValueError(_('must specify a service to register')) if self.verbose: print _('Registering "%s"...') % self.servicename # get the AI SMF service instance information try: self.instance = smf.AISCF(FMRI="system/install/server") except SystemError: raise SystemError( _("error: the system does not have the " "system/install/server SMF service")) # use the interfaces within the class if none are passed in if interfaces is None: interfaces = self.interfaces sdrefs = self._register_a_service(name=self.servicename, interfaces=interfaces, port=port, comments=comments) if sdrefs is not None: self.sdrefs[servicename] = sdrefs self._handle_events() else: raise AIMDNSError( cw( _('error: aiMDNSError: mDNS ad hoc ' 'registration failed for "%s" service') % self.servicename))
sys.stderr.write(estr) sys.exit(1) width = max(width, len(_('Manifest'))) fields = [[_('Manifest'), width]] fields.extend([[_('Criteria'), len(_('Criteria'))]]) do_header(fields) print_service_manifests(sdict, width, cwidth) if __name__ == '__main__': gettext.install("ai", "/usr/lib/locale") OPTIONS = parse_options() try: INST = smf.AISCF(FMRI="system/install/server") except KeyError: raise SystemExit(_("%s: error:\tThe system does not have the " + "system/install/server SMF service") % \ os.path.basename(sys.argv[0])) SERVICES = INST.services.keys() if not SERVICES: sys.stderr.write(_('%s: error: no services on this server.\n') % \ os.path.basename(sys.argv[0])) sys.exit(1) if OPTIONS.service and not OPTIONS.service in SERVICES: sys.stderr.write(_('%s: error: no local service named "%s".\n') % \ ( os.path.basename(sys.argv[0]), OPTIONS.service)) sys.exit(1)
query = AIdb.DBrequest(query, commit=True) db.getQueue().put(query) query.waitAns() # in case there's an error call the response function (which # will print the error) query.getResponse() if __name__ == '__main__': gettext.install("ai", "/usr/lib/locale") options = parse_options() # Get the SMF service object for the install service specified. try: svc = smf.AIservice(smf.AISCF(FMRI="system/install/server"), options.service_name) except KeyError: raise SystemExit( _("Error: Failed to find service %s") % options.service_name) # Get the install service's data directory and database path try: port = svc['txt_record'].rsplit(':')[-1] except KeyError: raise SystemExit( _("SMF data for service %s is corrupt.\n") % options.service_name) service_dir = os.path.abspath("/var/ai/" + port) database = os.path.join(service_dir, "AI.db") # Check that the service directory and database exist