Example #1
0
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))
Example #3
0
    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()
Example #4
0
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
Example #5
0
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
Example #6
0
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)
Example #7
0
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
Example #8
0
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>'
Example #9
0
    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
Example #10
0
    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))
Example #11
0
            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)
Example #12
0
    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