def test_clients(self):
        '''test clients'''

        props = {config.PROP_SERVICE_NAME: 's1'}
        config._write_service_config('s1', props)
        config.add_client_info(
            's1', '01AABBCCDDAABB', {
                config.FILES: ['/tmp/foo', '/tmp/bar'],
                config.BOOTARGS: 'console=ttya'
            })
        self.assertTrue(config.is_client('01AABBCCDDAABB'))
        self.assertFalse(config.is_client('01AABBCCDDAABC'))
        svc, clientdict = config.find_client('01AABBCCDDAABB')
        self.assertEqual(svc, 's1')
        self.assertEqual(clientdict[config.FILES], ['/tmp/foo', '/tmp/bar'])
        self.assertEqual(clientdict[config.BOOTARGS], 'console=ttya')

        config.add_client_info('s1', '01AAAAAAAAAAAA',
                               {config.FILES: ['/tmp/aaa', '/tmp/AAA']})
        clientdict = config.get_clients('s1')
        self.assertEqual(clientdict.keys(),
                         ['01AABBCCDDAABB', '01AAAAAAAAAAAA'])
        self.assertEqual(clientdict['01AAAAAAAAAAAA'][config.FILES],
                         ['/tmp/aaa', '/tmp/AAA'])

        config.remove_client_from_config('s1', '01AABBCCDDAABB')
        clientdict = config.get_clients('s1')
        self.assertTrue('01AABBCCDDAABB' not in clientdict)
Exemplo n.º 2
0
def do_update_basesvc(aliassvc, basesvcname):
    '''Updates the baseservice of an alias
    Input:
        aliassvc - service object of alias
        basesvcname - name of baseservice
    Returns:
        failures - list of errs encountered

    '''
    logging.debug('do_update_basesvc: alias=%s, basename=%s',
                  aliassvc.name, basesvcname)
    # Remove clients of alias
    clients = config.get_clients(aliassvc.name)
    for clientid in clients:
        logging.debug('removing client %s', clientid)
        clientctrl.remove_client(clientid, suppress_dhcp_msgs=True)

    failures = list()
    try:
        aliassvc.update_basesvc(basesvcname)
    except (OSError, config.ServiceCfgError, BootmgmtError) as err:
        print >> sys.stderr, \
            (_("Failed to set %(aliasname)s as alias of: %(bname)s") %
               {'aliasname': aliassvc.name, 'bname': basesvcname})
        print >> sys.stderr, err
        failures.append(err)
    except svc.MultipleUnmountError as err:
        print >> sys.stderr, _("Failed to disable alias")
        print >> sys.stderr, err
        failures.append(err)
    except svc.MountError as err:
        print >> sys.stderr, _("Failed to enable alias")
        print >> sys.stderr, err
        failures.append(err)
    except svc.UnsupportedAliasError as err:
        print >> sys.stderr, err
        failures.append(err)

   # Re-add clients to updated alias
    arch = aliassvc.arch
    for clientid in clients.keys():
        # strip off leading '01'
        client = clientid[2:]
        bootargs = None
        if config.BOOTARGS in clients[clientid]:
            bootargs = clients[clientid][config.BOOTARGS]
        logging.debug('re-adding clientid=%s, bootargs=%s', clientid, bootargs)

        # Don't suppress messages, because user may need to update
        # DHCP configuration
        try:
            create_client.create_new_client(arch, aliassvc, client,
                bootargs=bootargs, suppress_dhcp_msgs=False)
        except BootmgmtError as err:
            failures.append(err)
            print >> sys.stderr, (_('\nError: Unable to recreate client, '
                                    '%(client)s:\n%(error)s') %
                                    {'client': client, 'error': err})
    return failures
Exemplo n.º 3
0
def find_clients(lservices, sname=None):
    """
    find_clients() returns a dictionary that contains a list of
    dictionaries.

    The service name is the key for the main dictionary and the
    client, image path, and arch are members of the subdictionary,
    as follows:

        {
          'service1': [
                { 'ipath':<path1>, 'client':<client1>, 'arch': <arch>},
                ....
                      ],
          ....
        }

    Args
        lservices = config.get_all_service_props()
        sname - service name, if only interesetd in clients of a
                specific service

    Returns
        dictionary of a list of dictionaries

    Raises
        None

    """
    sdict = dict()
    for servicename in lservices.keys():
        if sname and sname != servicename:
            continue
        try:
            service = AIService(servicename)
        except VersionError as version_err:
            warn_version(version_err)
            continue
        arch = which_arch(service)
        image_path = [service.image.path]
        client_info = config.get_clients(servicename)
        for clientkey in client_info:
            # strip off the leading '01' and reinsert ':'s
            client = AIdb.formatValue('mac', clientkey[2:])
            tdict = {'client': client, 'ipath': image_path, 'arch': arch}
            if servicename in sdict:  # existing service name
                slist = sdict[servicename]
                slist.extend([tdict])
                sdict[servicename] = slist
            else:  # new service name key
                sdict[servicename] = [tdict]
    return sdict
Exemplo n.º 4
0
def find_clients(lservices, sname=None):
    """
    find_clients() returns a dictionary that contains a list of
    dictionaries.

    The service name is the key for the main dictionary and the
    client, image path, and arch are members of the subdictionary,
    as follows:

        {
          'service1': [
                { 'ipath':<path1>, 'client':<client1>, 'arch': <arch>},
                ....
                      ],
          ....
        }

    Args
        lservices = config.get_all_service_props()
        sname - service name, if only interesetd in clients of a
                specific service

    Returns
        dictionary of a list of dictionaries

    Raises
        None

    """
    sdict = dict()
    for servicename in lservices.keys():
        if sname and sname != servicename:
            continue
        try:
            service = AIService(servicename)
        except VersionError as version_err:
            warn_version(version_err)
            continue
        arch = which_arch(service)
        image_path = [service.image.path]
        client_info = config.get_clients(servicename)
        for clientkey in client_info:
            # strip off the leading '01' and reinsert ':'s
            client = AIdb.formatValue('mac', clientkey[2:])
            tdict = {'client': client, 'ipath': image_path, 'arch': arch}
            if servicename in sdict:  # existing service name
                slist = sdict[servicename]
                slist.extend([tdict])
                sdict[servicename] = slist
            else:  # new service name key
                sdict[servicename] = [tdict]
    return sdict
Exemplo n.º 5
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)

    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()
def do_rename_service(cmd_options=None):
    '''Rename a service.

    Note: Errors that occur during the various rename stages
    are printed, but the other stages will continue, with the hopes
    of leaving the final product as close to functional as possible

    '''
    # check that we are root
    if os.geteuid() != 0:
        raise SystemExit(_("Error: Root privileges are required for this "
                           "command.\n"))

    (svcname, newsvcname) = parse_options(cmd_options)

    # Ensure the service to rename is a valid service
    if not config.is_service(svcname):
        raise SystemExit(_("\nFailed to find service %s\n") % svcname)

    # Ensure the new name is not already a service
    if config.is_service(newsvcname):
        raise SystemExit(_("\nService or alias already exists: %s\n") %
                           newsvcname)

    # Don't allow renaming to/from the 'default-<arch>' aliases
    if svcname in DEFAULT_ARCH:
        raise SystemExit(_('\nYou may not rename the "%s" service.\n') %
                           svcname)

    if newsvcname in DEFAULT_ARCH:
        raise SystemExit(cw(_('\nYou may not rename a service to be the '
                              'default service for an architecture. To create '
                              'the default-sparc or default-i386 service '
                              'aliases, use "installadm create-service '
                              '-t|--aliasof."\n')))

    # Unmount old service
    was_mounted = False
    try:
        oldservice = AIService(svcname)
        if oldservice.mounted():
            was_mounted = True
            logging.debug("disabling %s", svcname)
            oldservice.disable(force=True)
    except (MountError, ImageError) as err:
        raise SystemExit(err)

    # remove old mountpoint
    try:
        os.rmdir(oldservice.mountpoint)
    except OSError as err:
        # Just make a note if unable to cleanup mountpoint
        logging.debug(err)

    # Remove clients whose base service has been renamed
    clients = config.get_clients(svcname)
    for clientid in clients.keys():
        clientctrl.remove_client(clientid)

    oldservice.rename(newsvcname)

    # Update aliases whose base service has been renamed
    aliases = config.get_aliased_services(svcname)
    failures = list()
    for alias in aliases:
        props = {config.PROP_ALIAS_OF: newsvcname}
        config.set_service_props(alias, props)

    # Mount the renamed service if it was mounted
    newservice = AIService(newsvcname)
    if was_mounted:
        try:
            logging.debug("enabling %s", newsvcname)
            newservice.enable()
        except (MountError, ImageError) as err:
            failures.append(err)
            print >> sys.stderr, err

    # Re-add clients whose base service has been renamed
    arch = newservice.arch
    for clientid in clients.keys():
        # strip off leading '01'
        client = clientid[2:]
        bootargs = None
        if config.BOOTARGS in clients[clientid]:
            bootargs = clients[clientid][config.BOOTARGS]
        create_client.create_new_client(arch, newservice, client,
                                        bootargs=bootargs)

    if failures:
        return 1
    else:
        return 0
Exemplo n.º 7
0
def do_rename_service(cmd_options=None):
    '''Rename a service.

    Note: Errors that occur during the various rename stages
    are printed, but the other stages will continue, with the hopes
    of leaving the final product as close to functional as possible

    '''
    # check that we are root
    if os.geteuid() != 0:
        raise SystemExit(_("Error: Root privileges are required for this "
                           "command.\n"))

    (svcname, newsvcname) = parse_options(cmd_options)

    # Ensure the service to rename is a valid service
    if not config.is_service(svcname):
        raise SystemExit(_("\nFailed to find service %s\n") % svcname)

    # Ensure the new name is not already a service
    if config.is_service(newsvcname):
        raise SystemExit(_("\nService or alias already exists: %s\n") %
                           newsvcname)

    # Don't allow renaming to/from the 'default-<arch>' aliases
    if svcname in DEFAULT_ARCH:
        raise SystemExit(_('\nYou may not rename the "%s" service.\n') %
                           svcname)

    if newsvcname in DEFAULT_ARCH:
        raise SystemExit(cw(_('\nYou may not rename a service to be the '
                              'default service for an architecture. To create '
                              'the default-sparc or default-i386 service '
                              'aliases, use "installadm create-service '
                              '-t|--aliasof."\n')))

    # Unmount old service
    was_mounted = False
    try:
        oldservice = AIService(svcname)
        if oldservice.mounted():
            was_mounted = True
            logging.debug("disabling %s", svcname)
            oldservice.disable(force=True)
    except (MountError, ImageError) as err:
        raise SystemExit(err)

    # remove old mountpoint
    try:
        os.rmdir(oldservice.mountpoint)
    except OSError as err:
        # Just make a note if unable to cleanup mountpoint
        logging.debug(err)

    # Remove clients whose base service has been renamed
    clients = config.get_clients(svcname)
    for clientid in clients.keys():
        clientctrl.remove_client(clientid)

    oldservice.rename(newsvcname)

    # Update aliases whose base service has been renamed
    aliases = config.get_aliased_services(svcname)
    failures = list()
    for alias in aliases:
        props = {config.PROP_ALIAS_OF: newsvcname}
        config.set_service_props(alias, props)

    # Mount the renamed service if it was mounted
    newservice = AIService(newsvcname)
    if was_mounted:
        try:
            logging.debug("enabling %s", newsvcname)
            newservice.enable()
        except (MountError, ImageError) as err:
            failures.append(err)
            print >> sys.stderr, err

    # Re-add clients whose base service has been renamed
    arch = newservice.arch
    for clientid in clients.keys():
        # strip off leading '01'
        client = clientid[2:]
        bootargs = None
        if config.BOOTARGS in clients[clientid]:
            bootargs = clients[clientid][config.BOOTARGS]
        create_client.create_new_client(arch, newservice, client,
                                        bootargs=bootargs)

    if failures:
        return 1
    else:
        return 0