def transaction(self): """Return all transactions to re-configure networking FIXME this should be rewritten o allow more fine grained progress informations """ class ConfigureNIC(utils.Transaction.Element): title = "Configuring NIC" def prepare(self): self.logger.debug("Psuedo preparing ovirtnode.Network") def commit(self): from ovirtnode.network import Network as oNetwork net = oNetwork() net.configure_interface() net.save_network_configuration() #utils.AugeasWrapper.force_reload() class ReloadNetworkConfiguration(utils.Transaction.Element): title = "Reloading network configuration" def commit(self): utils.AugeasWrapper.force_reload() utils.network.reset_resolver() tx = utils.Transaction("Applying new network configuration") tx.append(ConfigureNIC()) tx.append(ReloadNetworkConfiguration()) return tx
def on_merge(self, effective_changes): self.logger.debug("Saving logging page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) txs = utils.Transaction(_("Updating logging related configuration")) # If any logrotate key changed ... logrotate_keys = ["logrotate.max_size", "logrotate.interval"] if changes.contains_any(logrotate_keys): # Get all logrotate values fomr the effective model model = defaults.Logrotate() # And update the defaults model.update(*effective_model.values_for(logrotate_keys)) txs += model.transaction() rsyslog_keys = ["rsyslog.address", "rsyslog.port"] if changes.contains_any(rsyslog_keys): model = defaults.Syslog() model.update(*effective_model.values_for(rsyslog_keys)) txs += model.transaction() netconsole_keys = ["netconsole.address", "netconsole.port"] if changes.contains_any(netconsole_keys): model = defaults.Netconsole() model.update(*effective_model.values_for(netconsole_keys)) txs += model.transaction() progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run()
def transaction(self): cfg = dict(self.retrieve()) pwauth, num_bytes, disable_aesni = (cfg["pwauth"], cfg["num_bytes"], cfg["disable_aesni"]) ssh = utils.security.Ssh() class ConfigurePasswordAuthentication(utils.Transaction.Element): title = "Configuring SSH password authentication" def commit(self): ssh.password_authentication(pwauth) class ConfigureStrongRNG(utils.Transaction.Element): title = "Configuring SSH strong RNG" def commit(self): ssh.strong_rng(num_bytes) class ConfigureAESNI(utils.Transaction.Element): title = "Configuring SSH AES NI" def commit(self): ssh.disable_aesni(disable_aesni) tx = utils.Transaction("Configuring SSH") if pwauth in [True, False]: tx.append(ConfigurePasswordAuthentication()) if num_bytes: tx.append(ConfigureStrongRNG()) if disable_aesni in [True, False]: tx.append(ConfigureAESNI()) return tx
def transaction(self, cim_password): cfg = self.retrieve() enabled = cfg["enabled"] tx = utils.Transaction("Configuring CIM") class ConfigureCIM(utils.Transaction.Element): title = "Enabling CIM" if enabled else "Disabling CIM" def commit(self): action = "restart" if enabled else "stop" try: system.service("ovirt-cim", action) self.logger.debug("Configured CIM successfully") except RuntimeError: raise TransactionError("CIM configuration failed") class SetCIMPassword(utils.Transaction.Element): title = "Setting CIM password" def commit(self): create_cim_user() if not cim_password: raise RuntimeError("CIM password is missing.") from ovirtnode.password import set_password if not set_password(cim_password, "cim"): raise RuntimeError("Setting CIM Password Failed") tx.append(ConfigureCIM()) if enabled: tx.append(SetCIMPassword()) return tx
def __build_transaction(self): """Determin what kind of transaction to build Builds transactions for: - Installation - Upgrade """ cfg = self.__build_config() self.logger.debug("Building transaction") tx = utils.Transaction("Installation") if cfg["method"] in ["install"]: tx += [ self.UpdateDefaultsFromModels(cfg), self.PartitionAndFormat(cfg["installation.devices"]), self.SetPassword(cfg["root.password_confirmation"]), self.InstallImageAndBootloader(cfg["boot.device"]), self.SetKeyboardLayout(cfg["keyboard.layout"]) ] elif cfg["method"] in ["upgrade", "downgrade", "reinstall"]: tx.title = "Update" tx += [self.InstallImageAndBootloader()] new_password = cfg.get("upgrade.password_confirmation", None) if new_password: tx += [self.SetPassword(new_password)] self.logger.debug("Built transaction: %s" % tx) return tx
def on_merge(self, effective_changes): self.logger.debug("Saving SNMP page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) snmp_keys = ["snmp.password", "snmp.enabled"] txs = utils.Transaction("Updating SNMP configuration") if changes.contains_any(snmp_keys): is_enabled = effective_model["snmp.enabled"] pw = effective_model["snmp.password"] if is_enabled and len(pw) == 0: txt = "Unable to configure SNMP without a password!" self._confirm_dialog = ui.InfoDialog("dialog.confirm", "SNMP Error", txt) return self._confirm_dialog else: model = snmp_model.SNMP() model.update(is_enabled) txs += model.transaction(snmp_password=pw) progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run() return self.ui_content()
def on_merge(self, effective_changes): self.logger.debug("Saving remote storage page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) txs = utils.Transaction("Updating remote storage configuration") iscsi_keys = ["iscsi.initiator_name"] if changes.contains_any(iscsi_keys): model = defaults.iSCSI() args = effective_model.values_for(iscsi_keys) args += [None, None, None] # No target config model.update(*args) txs += model.transaction() nfsv4_keys = ["nfsv4.domain"] if changes.contains_any(nfsv4_keys): model = defaults.NFSv4() args = effective_model.values_for(nfsv4_keys) model.update(*args) txs += model.transaction() progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run()
def transaction(self): m = Timeservers().retrieve() servers = m["servers"] class WriteConfiguration(utils.Transaction.Element): title = "Writing timeserver configuration" def commit(self): aug = AugeasWrapper() p = "/files/etc/ntp.conf" aug.remove(p, False) aug.set(p + "/driftfile", "/var/lib/ntp/drift", False) aug.set(p + "/includefile", "/etc/ntp/crypto/pw", False) aug.set(p + "/keys", "/etc/ntp/keys", False) aug.save() config.network.timeservers(servers) utils.fs.Config().persist("/etc/ntp.conf") class ApplyConfiguration(utils.Transaction.Element): title = "Restarting time services" def commit(self): system.service("ntpd", "stop", False) system.service("ntpdate", "start", False) system.service("ntpd", "start", False) tx = utils.Transaction("Configuring timeservers") tx.append(WriteConfiguration()) tx.append(ApplyConfiguration()) return tx
def transaction(self): cfg = self.retrieve() hostname = cfg["hostname"] class UpdateHostname(utils.Transaction.Element): title = "Setting hostname" def __init__(self, hostname): self.hostname = hostname def commit(self): from ovirtnode import network as onet, ovirtfunctions network = onet.Network() if self.hostname: network.remove_non_localhost() network.add_localhost_alias(self.hostname) else: network.remove_non_localhost() self.hostname = "localhost.localdomain" config.network.hostname(self.hostname) ovirtfunctions.ovirt_store_config("/etc/sysconfig/network") ovirtfunctions.ovirt_store_config("/etc/hosts") utils.network.reset_resolver() tx = utils.Transaction("Configuring hostname") tx.append(UpdateHostname(hostname)) return tx
def on_merge(self, effective_changes): self.logger.info("Saving Puppet config") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) puppet_keys = ["puppet.enabled", "puppet.server", "puppet.certname"] if changes.contains_any(puppet_keys): Puppet().update(*effective_model.values_for(puppet_keys)) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) txs = utils.Transaction("Configuring Puppet") if effective_changes.contains_any(["action.register"]): self.logger.debug("Connecting to puppet") txs += [ActivatePuppet()] if len(txs) > 0: progress_dialog = ui.TransactionProgressDialog( "dialog.txs", txs, self) progress_dialog.run() # Acts like a page reload return self.ui_content()
def transaction(self): """Derives the nameserver config from OVIRT_DNS 1. Parse nameservers from defaults 2. Update resolv.conf 3. Update ifcfg- (peerdns=no if manual resolv.conf) 4. Persist resolv.conf Args: servers: List of servers (str) """ aug = utils.AugeasWrapper() m = Nameservers().retrieve() tx = utils.Transaction("Configuring DNS") if not m["servers"]: self.logger.debug("No DNS server entry in default config") return tx servers = m["servers"] if servers is None or servers == "": self.logger.debug("No DNS servers configured " + "in default config") class UpdateResolvConf(utils.Transaction.Element): title = "Updating resolv.conf" def commit(self): # Write resolv.conf any way, sometimes without servers comment = ("Please make changes through the TUI. " + "Manual edits to this file will be " + "lost on reboot") aug.set("/files/etc/resolv.conf/#comment[1]", comment) # Now set the nameservers config.network.nameservers(servers) utils.fs.Config().persist("/etc/resolv.conf") utils.network.reset_resolver() class UpdatePeerDNS(utils.Transaction.Element): title = "Update PEERDNS statement in ifcfg-* files" def commit(self): # Set or remove PEERDNS for all ifcfg-* for nic in glob.glob("/etc/sysconfig/network-scripts/ifcfg-*"): if "ifcfg-lo" in nic: continue path = "/files%s/PEERDNS" % nic if len(servers) > 0: aug.set(path, "no") else: aug.remove(path) # FIXME what about restarting NICs to pickup peerdns? tx += [UpdateResolvConf(), UpdatePeerDNS()] return tx
def __build_transaction(self): self.__update_defaults_from_models() tx = utils.Transaction("Installation") tx.append(self.PartitionAndFormat()) tx.append(self.SetPassword("the-password")) tx.append(self.InstallBootloader()) return tx
def __legacy_transaction(self): class ConfigureTimeservers(utils.Transaction.Element): title = "Setting timeservers" def commit(self): import ovirtnode.network as onet net = onet.Network() net.configure_ntp() net.save_ntp_configuration() tx = utils.Transaction("Configuring timeservers") tx.append(ConfigureTimeservers()) return tx
def transaction(self): cfg = dict(self.retrieve()) domain = cfg["domain"] class ConfigureNfsv4(utils.Transaction.Element): title = "Setting NFSv4 domain" def commit(self): nfsv4 = storage.NFSv4() nfsv4.domain(domain) tx = utils.Transaction("Configuring NFSv4") tx.append(ConfigureNfsv4()) return tx
def __legacy_transaction(self): class ConfigureNameservers(utils.Transaction.Element): title = "Setting namservers" def commit(self): import ovirtnode.network as onet net = onet.Network() net.configure_dns() utils.network.reset_resolver() tx = utils.Transaction("Configuring nameservers") tx.append(ConfigureNameservers()) return tx
def transaction(self): cfg = dict(self.retrieve()) max_size = cfg["max_size"] class CreateLogrotateConfig(utils.Transaction.Element): title = "Setting logrotate maximum logfile size" def commit(self): import ovirtnode.log as olog olog.set_logrotate_size(max_size) tx = utils.Transaction("Configuring logrotate") tx.append(CreateLogrotateConfig()) return tx
def transaction(self): cfg = dict(self.retrieve()) initiator_name = cfg["name"] class ConfigureIscsiInitiator(utils.Transaction.Element): title = "Setting the iSCSI initiator name" def commit(self): iscsi = utils.storage.iSCSI() iscsi.initiator_name(initiator_name) tx = utils.Transaction("Configuring the iSCSI Initiator") tx.append(ConfigureIscsiInitiator()) return tx
def transaction(self): cfg = dict(self.retrieve()) server, port = (cfg["server"], cfg["port"]) class CreateNetconsoleConfig(utils.Transaction.Element): title = "Setting netconsole server and port" def commit(self): import ovirtnode.log as olog olog.ovirt_netconsole(server, port) tx = utils.Transaction("Configuring netconsole") tx.append(CreateNetconsoleConfig()) return tx
def __legacy_transaction(self): cfg = dict(self.retrieve()) server, port = (cfg["server"], cfg["port"]) class CreateRsyslogConfig(utils.Transaction.Element): title = "Setting syslog server and port" def commit(self): import ovirtnode.log as olog olog.ovirt_rsyslog(server, port, "udp") tx = utils.Transaction("Configuring syslog") tx.append(CreateRsyslogConfig()) return tx
def transaction(self): cfg = self.retrieve() hostname = cfg["hostname"] class UpdateHostname(utils.Transaction.Element): title = "Setting hostname" def __init__(self, hostname): self.hostname = hostname def commit(self): aug = AugeasWrapper() localhost_entry = None for entry in aug.match("/files/etc/hosts/*"): if aug.get(entry + "/ipaddr") == "127.0.0.1": localhost_entry = entry break if not localhost_entry: raise RuntimeError("Couldn't find entry for localhost") # Remove all aliases for alias_entry in aug.match(localhost_entry + "/alias"): aug.remove(alias_entry, False) # ... and create a new one aliases = ["localhost", "localhost.localdomain"] if self.hostname: aliases.append(self.hostname) for _idx, alias in enumerate(aliases): idx = _idx + 1 p = "%s/alias[%s]" % (localhost_entry, idx) aug.set(p, alias, False) config.network.hostname(self.hostname) fs.Config().persist("/etc/hosts") fs.Config().persist("/etc/hostname") fs.Config().persist("/etc/sysconfig/network") utils.network.reset_resolver() tx = utils.Transaction("Configuring hostname") tx.append(UpdateHostname(hostname)) return tx
def transaction(self): cfg = dict(self.retrieve()) layout = cfg["layout"] class CreateKeyboardConfig(utils.Transaction.Element): title = "Setting keyboard layout" def commit(self): from ovirtnode.ovirtfunctions import ovirt_store_config kbd = utils.system.Keyboard() kbd.set_layout(layout) ovirt_store_config(["/etc/sysconfig/keyboard", "/etc/vconsole.conf"]) tx = utils.Transaction("Configuring keyboard layout") tx.append(CreateKeyboardConfig()) return tx
def transaction(self): cfg = dict(self.retrieve()) domain = cfg["domain"] class ConfigureNfsv4(utils.Transaction.Element): title = "Setting NFSv4 domain" def commit(self): nfsv4 = storage.NFSv4() nfsv4.domain(domain) fs.Config().persist(nfsv4.configfilename) system.service("rpcidmapd", "restart") process.check_call("nfsidmap -c") tx = utils.Transaction("Configuring NFSv4") tx.append(ConfigureNfsv4()) return tx
def transaction(self, snmp_password): cfg = self.retrieve() enabled = cfg["enabled"] tx = utils.Transaction("Configuring SNMP") class ConfigureSNMP(utils.Transaction.Element): state = ("Enabling" if enabled else "Disabling") title = "%s SNMP and setting the password" % state def commit(self): if enabled and snmp_password: enable_snmpd(snmp_password) else: disable_snmpd() tx.append(ConfigureSNMP()) return tx
def on_merge(self, effective_changes): self.logger.debug("Saving security page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) ssh_keys = [ "ssh.pwauth", "strongrng.num_bytes", "strongrng.disable_aesni" ] passwd_keys = [ "passwd.admin.password", "passwd.admin.password_confirmation" ] txs = utils.Transaction("Updating security configuration") if changes.contains_any(ssh_keys): model = defaults.SSH() model.update(*effective_model.values_for(ssh_keys)) txs += model.transaction() if changes.contains_any(passwd_keys): pw, pwc = effective_model.values_for(passwd_keys) if pw != pwc: raise exceptions.InvalidData("Passwords do not match") passwd = utils.security.Passwd() # Create a custom transaction element, because the password # is not handled/saved in the defaults file class SetAdminPasswd(utils.Transaction.Element): title = "Setting admin password" def commit(self): self.logger.debug("Setting admin password.") passwd.set_password("admin", pw) txs += [SetAdminPasswd()] progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run()
def transaction(self): # This method builds a transaction to modify the system # according to the values of self.keys # E.g. the value of OVIRT_TUNED_PROFILE needs to be passed to # the tuned client # We read the profile name from the defaults file profile = self.retrieve()["profile"] class CallTunedAdm(utils.Transaction.Element): title = "Requesting profile change" def commit(self): tuned.set_active_profile(profile) tx = utils.Transaction("Applying tuned configuration") if profile: # Only add the element if there is a profile to be set tx.append(CallTunedAdm()) return tx
def on_merge(self, effective_changes): self.logger.debug("Saving monitoring page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) collectd_keys = ["collectd.address", "collectd.port"] txs = utils.Transaction(_("Updating monitoring configuration")) if changes.contains_any(collectd_keys): model = defaults.Collectd() model.update(*effective_model.values_for(collectd_keys)) txs += model.transaction() progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run()
def on_merge(self, effective_changes): self.logger.debug("Saving keyboard page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) layout_keys = ["keyboard.layout"] txs = utils.Transaction("Updating keyboard related configuration") if changes.contains_any(layout_keys): model = defaults.Keyboard() model.update(*effective_model.values_for(layout_keys)) txs += model.transaction() progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self) progress_dialog.run()
def transaction(self): cfg = dict(self.retrieve()) password = cfg["password"] class ConfigureSNMP(utils.Transaction.Element): title = "Enabling/Disabling SNMP and setting the password" def commit(self): # FIXME snmp plugin needs to be placed somewhere else (in src) # pylint: disable-msg=E0611 from ovirt_config_setup import snmp # @UnresolvedImport # pylint: enable-msg=E0611 if password: snmp.enable_snmpd(password) else: snmp.disable_snmpd() tx = utils.Transaction("Configuring SNMP") tx.append(ConfigureSNMP()) return tx
def __legacy_transaction(self): cfg = dict(self.retrieve()) server, port = (cfg["server"], cfg["port"]) class ConfigureCollectd(utils.Transaction.Element): title = "Setting collect server and port" def commit(self): # pylint: disable-msg=E0611 from ovirt_config_setup import collectd # @UnresolvedImport # pylint: enable-msg=E0611 if collectd.write_collectd_config(server, port): self.logger.debug("Collectd was configured successfully") else: raise exceptions.TransactionError("Failed to configure " + "collectd") tx = utils.Transaction("Configuring collectd") tx.append(ConfigureCollectd()) return tx
def on_merge(self, effective_changes): """Applies the changes to the plugins model, will do all required logic Normally on_merge is called by pushing the SaveButton instance, in this case it is called by on_change """ self.logger.debug("Saving kdump page") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) kdump_keys = ["kdump.type", "kdump.ssh_location", "kdump.nfs_location"] txs = utils.Transaction("Updating kdump related configuration") if changes.contains_any(kdump_keys): model = defaults.KDump() ktype, sshloc, nfsloc = effective_model.values_for(kdump_keys) if ktype == "nfs": model.update(nfsloc, None, None) elif ktype == "ssh": model.update(None, sshloc, None) elif ktype == "local": model.update(None, None, True) else: model.update(None, None, None) txs += model.transaction() try: with self.application.ui.suspended(): console.reset() is_dry = self.application.args.dry progress_dialog = console.TransactionProgress(txs, is_dry) progress_dialog.run() console.writeln("\nPlease press any key to continue") console.wait_for_keypress() except Exception as e: self.logger.exception("Exception while configuring kdump") return InfoDialog("dialog.info", "An error occurred", e.message)