def set_aliasof(options): '''Change a service's base service''' logging.debug("set alias %s's basesvc to %s", options.svcname, options.value) basesvcname = options.value aliasname = options.svcname if not config.is_service(basesvcname): raise SystemExit( _('\nError: Service does not exist: %s\n') % basesvcname) if aliasname == basesvcname: raise SystemExit( _('\nError: Alias name same as service name: %s\n') % aliasname) aliassvc = svc.AIService(aliasname) if not aliassvc.is_alias(): raise SystemExit( _('\nError: Service exists, but is not an ' 'alias: %s\n') % aliasname) basesvc_arch = svc.AIService(basesvcname).arch aliassvc_arch = aliassvc.arch if basesvc_arch != aliassvc_arch: raise SystemExit( _("\nError: Architectures of service and alias " "are different.\n")) if aliassvc.is_aliasof(basesvcname): raise SystemExit( _("\nError: %s is already an alias of %s\n") % (aliasname, basesvcname)) if svc.AIService(basesvcname).is_alias(): raise SystemExit(_("\nError: Cannot alias to another alias.\n")) # Make sure we aren't creating inter dependencies all_aliases = config.get_aliased_services(aliasname, recurse=True) if basesvcname in all_aliases: raise SystemExit( cw( _("\nError: %s can not be made an alias of %s " "because %s is dependent on %s\n") % (aliasname, basesvcname, basesvcname, aliasname))) try: aliassvc.update_basesvc(basesvcname) except (OSError, config.ServiceCfgError) as err: raise SystemExit( _("Failed to set 'aliasof' property of : %s") % aliasname) except svc.MultipleUnmountError as err: print >> sys.stderr, _("Failed to disable alias") raise SystemExit(err) except svc.MountError as err: print >> sys.stderr, _("Failed to enable alias") raise SystemExit(err) except svc.UnsupportedAliasError as err: raise SystemExit(err)
def test_get_aliased_services(self): '''test get_aliased_services''' props = {config.PROP_SERVICE_NAME: 'base1'} config._write_service_config('base1', props) props = { config.PROP_SERVICE_NAME: 'alias1', config.PROP_ALIAS_OF: 'base1' } config._write_service_config('alias1', props) props = { config.PROP_SERVICE_NAME: 'alias2', config.PROP_ALIAS_OF: 'alias1' } config._write_service_config('alias2', props) aliased = config.get_aliased_services('base1') self.assertTrue(aliased == ['alias1']) aliased = config.get_aliased_services('base1', recurse=True) self.assertTrue(aliased == ['alias1', 'alias2'])
def set_aliasof(options): '''Change a service's base service''' logging.debug("set alias %s's basesvc to %s", options.svcname, options.value) basesvcname = options.value aliasname = options.svcname if not config.is_service(basesvcname): raise SystemExit(_('\nError: Service does not exist: %s\n') % basesvcname) if aliasname == basesvcname: raise SystemExit(_('\nError: Alias name same as service name: %s\n') % aliasname) aliassvc = svc.AIService(aliasname) if not aliassvc.is_alias(): raise SystemExit(_('\nError: Service exists, but is not an ' 'alias: %s\n') % aliasname) basesvc_arch = svc.AIService(basesvcname).arch aliassvc_arch = aliassvc.arch if basesvc_arch != aliassvc_arch: raise SystemExit(_("\nError: Architectures of service and alias " "are different.\n")) if aliassvc.is_aliasof(basesvcname): raise SystemExit(_("\nError: %s is already an alias of %s\n") % (aliasname, basesvcname)) if svc.AIService(basesvcname).is_alias(): raise SystemExit(_("\nError: Cannot alias to another alias.\n")) # Make sure we aren't creating inter dependencies all_aliases = config.get_aliased_services(aliasname, recurse=True) if basesvcname in all_aliases: raise SystemExit(cw(_("\nError: %s can not be made an alias of %s " "because %s is dependent on %s\n") % (aliasname, basesvcname, basesvcname, aliasname))) try: aliassvc.update_basesvc(basesvcname) except (OSError, config.ServiceCfgError) as err: raise SystemExit(_("Failed to set 'aliasof' property of : %s") % aliasname) except svc.MultipleUnmountError as err: print >> sys.stderr, _("Failed to disable alias") raise SystemExit(err) except svc.MountError as err: print >> sys.stderr, _("Failed to enable alias") raise SystemExit(err) except svc.UnsupportedAliasError as err: raise SystemExit(err)
def set_aliasof(options): '''Change a service's base service''' logging.debug("set alias %s's basesvc to %s", options.svcname, options.value) basesvcname = options.value aliasname = options.svcname if not config.is_service(basesvcname): raise SystemExit(_('\nError: Service does not exist: %s\n') % basesvcname) if aliasname == basesvcname: raise SystemExit(_('\nError: Alias name same as service name: %s\n') % aliasname) aliassvc = svc.AIService(aliasname) if not aliassvc.is_alias(): raise SystemExit(_('\nError: Service exists, but is not an ' 'alias: %s\n') % aliasname) basesvc_arch = svc.AIService(basesvcname).arch aliassvc_arch = aliassvc.arch if basesvc_arch != aliassvc_arch: raise SystemExit(_("\nError: Architectures of service and alias " "are different.\n")) if aliassvc.is_aliasof(basesvcname): raise SystemExit(_("\nError: %(aliasname)s is already an alias " "of %(svcname)s\n") % {'aliasname': aliasname, 'svcname': basesvcname}) if svc.AIService(basesvcname).is_alias(): raise SystemExit(_("\nError: Cannot alias to another alias.\n")) # Make sure we aren't creating inter dependencies all_aliases = config.get_aliased_services(aliasname, recurse=True) if basesvcname in all_aliases: raise SystemExit(cw(_("\nError: %(aliasname)s can not be made an " "alias of %(svcname)s because %(svcname)s is " "dependent on %(aliasname)s\n") % {'aliasname': aliasname, 'svcname': basesvcname})) failures = do_update_basesvc(aliassvc, basesvcname) if failures: return 1 return 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
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