Exemple #1
0
def should_be_default_for_arch(newservice):
    '''
    Determine if newservice should be the baseservice of default-<arch>
    (i.e., first service of architecture and aliasable)

    Input: service object for newly created service
    Returns: True if default-<arch> alias should be created
             False otherwise

    '''
    if newservice.image.version < 3:
        return False
    services = config.get_all_service_names()
    make_default = True
    for service in services:
        if service == newservice.name:
            continue
        svc = AIService(service)
        try:
            props = config.get_service_props(service)
            config.verify_key_properties(service, props)
        except config.ServiceCfgError as err:
            # if service is missing keys, print info and skip it
            print >> sys.stderr, err
            continue
        if svc.arch == newservice.arch and svc.image.version >= 3:
            make_default = False
            break

    logging.debug("should_be_default_for_arch service %s, arch=%s, returns %s",
                  newservice.name, newservice.arch, make_default)
    return make_default
    def _register_a_service(self, name, interfaces=None, port=0,
                            comments=None):
        '''Method: _register_a_service, private to class

        Description:
            Register a single service on the interfaces

        Args
            interfaces - the interfaces to register the service on
            instance   - the SMF service instance handle
            name       - the service name to be registered
            port       - the port that the service is listening on, if
                         port is 0 then registering a service listed in
                         the AI SMF service instance.
            comments   - comments for the ad hoc registered service

        Returns
            list_sdrefs - list of service references

        Raises
            AImDNSError - if SMF status property does not exist, OR
                          if SMF txt_record property does not exist, OR
                          if SMF port property does not exist.
        '''
        if not self.register_initialized:
            self.exclude = libaimdns.getboolean_property(common.SRVINST,
                                                         common.EXCLPROP)
            self.networks = libaimdns.getstrings_property(common.SRVINST,
                                                          common.NETSPROP)
            self.register_initialized = True

        smf_port = None
        # if port is 0 then processing an AI service
        if port == 0:
            serv = config.get_service_props(name)
            if not serv:
                raise AIMDNSError(cw(_('error: aiMDNSError: no such '
                                       'installation service "%s"') % name))

            # ensure the service is enabled
            if config.PROP_STATUS not in serv:
                raise AIMDNSError(cw(_('error: aiMDNSError: installation '
                                       'service key "status" property does '
                                       'not exist')))

            if serv[config.PROP_STATUS] != config.STATUS_ON:
                print(cw(_('warning: Installation service "%s" is not enabled '
                           % name)))
                return None

            smf_port = config.get_service_port(name)
            if not smf_port:
                try:
                    smf_port = libaimdns.getinteger_property(common.SRVINST,
                                                             common.PORTPROP)
                    smf_port = str(smf_port)
                except libaimdns.aiMDNSError, err:
                    raise AIMDNSError(cw(_('error: aiMDNSError: port property '
                                           'failure (%s)') % err))
 def test_get_service_props(self):
     '''test get_service_props'''
     svc = 'mysvc'
     props = {'dark': 'chocolate', 'green': 'tea'}
     config._write_service_config(svc, props)
     propdict = config.get_service_props(svc)
     self.assertEqual(propdict['version'], config.CURRENT_VERSION)
     self.assertEqual(propdict['dark'], 'chocolate')
     self.assertEqual(propdict['green'], 'tea')
Exemple #4
0
    def _signal_hup(self, signum, frame):
        '''Method: _signal_hup, class private
        Description:
            Callback invoked when SIGHUP is received

        Args
            signum - standard argument for callback, not used
            frame  - standard argument for callback, not used

        Returns
            None

        Raises
            None
        '''
        # get the new service keys and iterate over them
        services = config.get_all_service_names()
        for srv in services:
            # is this service already registered
            if srv not in self.instance_services or srv not in self.sdrefs:
                # need to register the service
                if self.verbose:
                    print _('Registering %s') % srv

                sdrefs = self._register_a_service(interfaces=self.interfaces,
                                                  name=srv)

                # save the service reference list in self.sdrefs
                if sdrefs is not None:
                    # self.sdrefs update, force restart of event loop
                    self._restart_loop = True
                    if srv in self.sdrefs:
                        self.sdrefs[srv].extend(sdrefs)
                    else:
                        self.sdrefs[srv] = sdrefs

        # check the old service keys for removed or disabled services
        for srv in self.instance_services:
            # get the service (srv) from the instance
            try:
                serv = config.get_service_props(srv)
            except KeyError:
                # not a catastrophic error for the class as additional
                # services can still be processed.  This error will be
                # caught in the service log file.
                sys.stderr.write(
                    _('warning: No such installation service, '
                      '%s\n') % srv)

                # remove the service references for the now non-existent
                # service that was just identified.  This can occur when
                # a service is deleted.
                if srv in self.sdrefs:
                    self._restart_loop = True
                    for sdref in self.sdrefs[srv]:
                        sdref.close()
                    del self.sdrefs[srv]

                continue

            # was the service removed or disabled
            if (srv not in services) or \
               (srv in self.sdrefs and
                serv[config.PROP_STATUS] == config.STATUS_OFF):

                if self.verbose:
                    print _('Unregistering %s') % srv

                # remove the registered service
                if srv in self.sdrefs:
                    # self.sdrefs update, force restart of event loop
                    self._restart_loop = True
                    for sdref in self.sdrefs[srv]:
                        sdref.close()
                    del self.sdrefs[srv]

        # save the new services list
        self.instance_services = services
Exemple #5
0
    def _register_a_service(self,
                            name,
                            interfaces=None,
                            port=0,
                            comments=None):
        '''Method: _register_a_service, private to class

        Description:
            Register a single service on the interfaces

        Args
            interfaces - the interfaces to register the service on
            instance   - the SMF service instance handle
            name       - the service name to be registered
            port       - the port that the service is listening on, if
                         port is 0 then registering a service listed in
                         the AI SMF service instance.
            comments   - comments for the ad hoc registered service

        Returns
            list_sdrefs - list of service references

        Raises
            AImDNSError - if SMF status property does not exist, OR
                          if SMF txt_record property does not exist, OR
                          if SMF port property does not exist.
        '''
        if not self.register_initialized:
            self.exclude = libaimdns.getboolean_property(
                common.SRVINST, common.EXCLPROP)
            self.networks = libaimdns.getstrings_property(
                common.SRVINST, common.NETSPROP)
            self.register_initialized = True

        smf_port = None
        # if port is 0 then processing an AI service
        if port == 0:
            serv = config.get_service_props(name)
            if not serv:
                raise AIMDNSError(
                    cw(
                        _('error: aiMDNSError: no such '
                          'installation service "%s"') % name))

            # ensure the service is enabled
            if config.PROP_STATUS not in serv:
                raise AIMDNSError(
                    cw(
                        _('error: aiMDNSError: installation '
                          'service key "status" property does '
                          'not exist')))

            if serv[config.PROP_STATUS] != config.STATUS_ON:
                print(
                    cw(
                        _('warning: Installation service "%s" is not enabled '
                          % name)))
                return None

            smf_port = config.get_service_port(name)
            if not smf_port:
                try:
                    smf_port = libaimdns.getinteger_property(
                        common.SRVINST, common.PORTPROP)
                    smf_port = str(smf_port)
                except libaimdns.aiMDNSError, err:
                    raise AIMDNSError(
                        cw(
                            _('error: aiMDNSError: port property '
                              'failure (%s)') % err))
Exemple #6
0
def parse_options(cmd_options=None):
    '''
    Parse and validate options
    '''
    def check_MAC_address(option, opt_str, value, parser):
        '''
        Check MAC address as an OptionParser callback
        Postcondition: sets value to proper option if check passes
        Raises: OptionValueError if MAC address is malformed
        '''
        try:
            value = str(com.MACAddress(value))
        except com.MACAddress.MACAddressError as err:
            raise OptionValueError(str(err))
        setattr(parser.values, option.dest, value)

    usage = '\n' + get_usage()
    parser = OptionParser(usage=usage)

    # accept multiple -b options (so append to a list)
    parser.add_option("-b",
                      "--boot-args",
                      dest="boot_args",
                      action="append",
                      type="string",
                      nargs=1,
                      help=_("boot arguments to pass to Solaris kernel"))
    parser.add_option("-e",
                      "--macaddr",
                      dest="mac_address",
                      action="callback",
                      nargs=1,
                      type="string",
                      help=_("MAC address of client to add"),
                      callback=check_MAC_address)
    parser.add_option("-n",
                      "--service",
                      dest="service_name",
                      action="store",
                      type="string",
                      help=_("Service to associate client with"),
                      nargs=1)
    (options, args) = parser.parse_args(cmd_options)

    if args:
        parser.error(_("Unexpected argument(s): %s" % args))

    # check that we got a service name and mac address
    if options.service_name is None:
        parser.error(
            _("Service name is required "
              "(-n|--service <service name>)."))
    if options.mac_address is None:
        parser.error(_("MAC address is required (-e|--macaddr <macaddr>)."))

    # Verify that the server settings are not obviously broken.
    # These checks cannot be complete, but check for things which
    # will definitely cause failure.
    logging.debug("Calling %s", com.CHECK_SETUP_SCRIPT)
    ret = Popen([com.CHECK_SETUP_SCRIPT]).wait()
    if ret:
        raise SystemExit(1)

    # validate service name
    try:
        com.validate_service_name(options.service_name)
    except ValueError as err:
        raise SystemExit(err)

    # check that the service exists
    service_props = config.get_service_props(options.service_name)
    if not service_props:
        raise SystemExit(
            _("The specified service does not exist: %s\n") %
            options.service_name)

    # get the image_path from the service
    try:
        # set image to be a InstalladmImage object
        image = svc.AIService(options.service_name).image
    except KeyError:
        raise SystemExit(
            _("\nThe specified service does not have an "
              "image_path property.\n"))

    # ensure we are not passed bootargs for a SPARC as we do not
    # support that
    if options.boot_args and image.arch == "sparc":
        parser.error(_("Boot arguments not supported for SPARC clients.\n"))

    options.arch = image.arch

    logging.debug("options = %s", options)

    return options
Exemple #7
0
def delete_specified_service(service_name, auto_remove, noprompt):
    ''' Delete the specified Automated Install Service
    Input: service_name - service name
           auto_remove - boolean, True if dep. aliases and clients should
                         be removed, False otherwise
           noprompt - boolean, True if warning about removing
                           default-<arch> service should be suppressed
    '''
    logging.debug("delete_specified_service %s %s %s", service_name,
                  auto_remove, noprompt)

    # get service properties
    svcprops = config.get_service_props(service_name)
    service = AIService(service_name)
    
    # If the '-r' option has not been specified, look for all
    # dependent aliases and clients
    all_aliases = config.get_aliased_services(service_name, recurse=True)
    if not auto_remove:
        all_clients = config.get_clients(service_name).keys()
        for ale in all_aliases:
            all_clients.extend(config.get_clients(ale).keys())

        # if any aliases or clients are dependent on this service, exit
        if all_aliases or all_clients:
            raise SystemExit(cw(_("\nError: The following aliases and/or "
                                  "clients are dependent on this service:\n\n"
                                  "%s\n\nPlease update or delete them prior "
                                  "to deleting this service or rerun this "
                                  "command using the -r|--autoremove option "
                                  "to have them automatically removed.\n") %
                                  '\n'.join(all_aliases + all_clients)))

    # Prompt user if they are deleting the default-sparc or default-i386 alias
    if not noprompt:
        sname = None
        if service_name in DEFAULT_ARCH:
            sname = service_name
        else:
            default_alias = set(DEFAULT_ARCH) & set(all_aliases)
            if default_alias:
                sname = ''.join(default_alias)
        if sname:
            arch = sname.split('default-')[1]
            _warning = """
            WARNING: The service you are deleting, or a dependent alias, is
            the alias for the default %(arch)s service. Without the '%(name)s'
            service, %(arch)s clients will fail to boot unless explicitly
            assigned to a service using the create-client command.
            """ % {'arch': arch,
                   'name': sname}

            print >> sys.stderr, cw(_(_warning))
            prompt = _("Are you sure you want to delete this alias? [y/N]: ")
            if not com.ask_yes_or_no(prompt):
                raise SystemExit(1)

    # If there are dependent aliases or clients, then remove these first
    aliases = config.get_aliased_services(service_name)
    for dependent in aliases:
        logging.debug("recursively calling delete_specified_service for %s",
                       dependent)
        delete_specified_service(dependent, True, True)
    
    clients = config.get_clients(service_name).keys()
    for dependent in clients:
        logging.debug("calling remove_client for %s", dependent)
        clientctrl.remove_client(dependent)
    
    logging.debug("now deleting service %s", service_name)

    # remove DHCP bootfile configuration for this service, if set
    remove_dhcp_configuration(service)

    # stop the service first (avoid pulling files out from under programs)
    try:
        service.delete()
    except StandardError as err:
        # Bail out if the service could not be unmounted during the disable,
        # as it won't be possible to delete necessary files.
        print >> sys.stderr, _("\nService could not be deleted.")
        raise SystemExit(err)

    # if this was the last service, go to maintenance
    config.check_for_enabled_services()
Exemple #8
0
def do_disable_service(cmd_options=None):
    ''' Disable a service

    Disable the specified service and optionally update the service's
    properties to reflect the new status.

    Input:
        List of command line options
    Return:
        None
    Raises:
        SystemExit if missing permissions, invalid service name, or
        if attempt to place smf service in maintenance fails.

    '''
    logging.debug('**** START do_disable_service ****')

    # check for authorization and euid
    try:
        check_auth_and_euid(SERVICE_AUTH)
    except UnauthorizedUserError as err:
        raise SystemExit(err)

    usage = '\n' + get_disable_usage()
    parser = OptionParser(usage=usage)

    (options, args) = parser.parse_args(cmd_options)

    # Check for correct number of args
    if len(args) != 1:
        if len(args) == 0:
            parser.error(_("Missing required argument, <svcname>"))
        else:
            parser.error(_("Too many arguments: %s") % args)

    svcname = args[0]

    # validate service name
    try:
        validate_service_name(svcname)
    except ValueError as err:
        raise SystemExit(err)

    if not config.is_service(svcname):
        err_msg = _("The service does not exist: %s\n") % svcname
        parser.error(err_msg)

    prop_data = config.get_service_props(svcname)

    if prop_data and config.PROP_STATUS not in prop_data:
        err_msg = _("The property, status, is missing for %s.\n") % svcname
        parser.error(err_msg)

    if prop_data[config.PROP_STATUS] == config.STATUS_OFF:
        err_msg = _("The service is not running: %s\n") % svcname
        parser.error(err_msg)

    try:
        logging.debug("Disabling install service %s", svcname)
        service = AIService(svcname)
        service.disable(force=True)
    except (config.ServiceCfgError, aismf.ServicesError, MountError) as err:
        raise SystemExit(err)
    except CalledProcessError:
        return 1
    def _signal_hup(self, signum, frame):
        '''Method: _signal_hup, class private
        Description:
            Callback invoked when SIGHUP is received

        Args
            signum - standard argument for callback, not used
            frame  - standard argument for callback, not used

        Returns
            None

        Raises
            None
        '''
        # get the new service keys and iterate over them
        services = config.get_all_service_names()
        for srv in services:
            # is this service already registered
            if srv not in self.instance_services or srv not in self.sdrefs:
                # need to register the service
                if self.verbose:
                    print _('Registering %s') % srv

                sdrefs = self._register_a_service(interfaces=self.interfaces,
                                                  name=srv)

                # save the service reference list in self.sdrefs
                if sdrefs is not None:
                    # self.sdrefs update, force restart of event loop
                    self._restart_loop = True
                    if srv in self.sdrefs:
                        self.sdrefs[srv].extend(sdrefs)
                    else:
                        self.sdrefs[srv] = sdrefs

        # check the old service keys for removed or disabled services
        for srv in self.instance_services:
            # get the service (srv) from the instance
            try:
                serv = config.get_service_props(srv)
            except KeyError:
                # not a catastrophic error for the class as additional
                # services can still be processed.  This error will be
                # caught in the service log file.
                sys.stderr.write(_('warning: No such installation service, '
                                   '%s\n') % srv)

                # remove the service references for the now non-existent
                # service that was just identified.  This can occur when
                # a service is deleted.
                if srv in self.sdrefs:
                    self._restart_loop = True
                    for sdref in self.sdrefs[srv]:
                        sdref.close()
                    del self.sdrefs[srv]

                continue

            # was the service removed or disabled
            if (srv not in services) or \
               (srv in self.sdrefs and
                serv[config.PROP_STATUS] == config.STATUS_OFF):

                if self.verbose:
                    print _('Unregistering %s') % srv

                # remove the registered service
                if srv in self.sdrefs:
                    # self.sdrefs update, force restart of event loop
                    self._restart_loop = True
                    for sdref in self.sdrefs[srv]:
                        sdref.close()
                    del self.sdrefs[srv]

        # save the new services list
        self.instance_services = services
def parse_options(cmd_options=None):
    '''
    Parse and validate options
    '''

    def check_MAC_address(option, opt_str, value, parser):
        '''
        Check MAC address as an OptionParser callback
        Postcondition: sets value to proper option if check passes
        Raises: OptionValueError if MAC address is malformed
        '''
        try:
            value = str(com.MACAddress(value))
        except com.MACAddress.MACAddressError as err:
            raise OptionValueError(str(err))
        setattr(parser.values, option.dest, value)

    usage = '\n' + get_usage()
    parser = OptionParser(usage=usage)

    # accept multiple -b options (so append to a list)
    parser.add_option("-b", "--boot-args", dest="boot_args", action="append",
                      type="string", nargs=1,
                      help=_("boot arguments to pass to Illumos kernel"))
    parser.add_option("-e", "--macaddr", dest="mac_address", action="callback",
                      nargs=1, type="string",
                      help=_("MAC address of client to add"),
                      callback=check_MAC_address)
    parser.add_option("-n", "--service", dest="service_name", action="store",
                      type="string",
                      help=_("Service to associate client with"), nargs=1)
    (options, args) = parser.parse_args(cmd_options)

    if args: 
        parser.error(_("Unexpected argument(s): %s" % args))

    # check that we got a service name and mac address
    if options.service_name is None:
        parser.error(_("Service name is required "
                       "(-n|--service <service name>)."))
    if options.mac_address is None:
        parser.error(_("MAC address is required (-e|--macaddr <macaddr>)."))

    # Verify that the server settings are not obviously broken.
    # These checks cannot be complete, but check for things which 
    # will definitely cause failure.
    logging.debug("Calling %s", com.CHECK_SETUP_SCRIPT)
    ret = Popen([com.CHECK_SETUP_SCRIPT]).wait()
    if ret:
        raise SystemExit(1)

    # validate service name
    try:
        com.validate_service_name(options.service_name)
    except ValueError as err:
        raise SystemExit(err)

    # check that the service exists
    service_props = config.get_service_props(options.service_name)
    if not service_props:
        parser.error(_("The specified service does not exist: %s\n") %
                       options.service_name)

    # get the image_path from the service
    try:
        # set image to be a InstalladmImage object
        image = svc.AIService(options.service_name).image
    except KeyError:
        raise SystemExit(_("\nThe specified service does not have an "
                           "image_path property.\n"))

    # ensure we are not passed bootargs for a SPARC as we do not
    # support that
    if options.boot_args and image.arch == "sparc":
        parser.error(_("Boot arguments not supported for SPARC clients.\n"))

    options.arch = image.arch

    logging.debug("options = %s", options)

    return options