Fabian Deutsch has uploaded a new change for review. Change subject: model: Update model structure ......................................................................
model: Update model structure There is now a class for each component that can be configured using node's default file. Change-Id: Ie04c429322a8bb1dd6ca2e2e92a6e6f20fc3b745 Signed-off-by: Fabian Deutsch <[email protected]> --- M scripts/tui/src/ovirt/node/app.py M scripts/tui/src/ovirt/node/config/__init__.py A scripts/tui/src/ovirt/node/config/defaults.py D scripts/tui/src/ovirt/node/model.py M scripts/tui/src/ovirt/node/plugins/kdump_page.py M scripts/tui/src/ovirt/node/plugins/keyboard_page.py M scripts/tui/src/ovirt/node/plugins/logging_page.py M scripts/tui/src/ovirt/node/plugins/monitoring_page.py M scripts/tui/src/ovirt/node/plugins/network_page.py M scripts/tui/src/ovirt/node/plugins/remote_storage_page.py M scripts/tui/src/ovirt/node/plugins/security_page.py M scripts/tui/src/ovirt/node/plugins/snmp_page.py M scripts/tui/src/ovirt/node/plugins/status_page.py M scripts/tui/src/ovirt/node/ui/builder.py M scripts/tui/src/ovirt/node/ui/tui.py M scripts/tui/src/ovirt/node/utils/__init__.py 16 files changed, 309 insertions(+), 208 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/28/9928/1 diff --git a/scripts/tui/src/ovirt/node/app.py b/scripts/tui/src/ovirt/node/app.py index 9da0916..4aaa4ab 100644 --- a/scripts/tui/src/ovirt/node/app.py +++ b/scripts/tui/src/ovirt/node/app.py @@ -34,6 +34,7 @@ import ovirt.node.ui.tui import ovirt.node.utils +import ovirt.node.plugins class Application(object): diff --git a/scripts/tui/src/ovirt/node/config/__init__.py b/scripts/tui/src/ovirt/node/config/__init__.py index efba4d2..5bcef55 100644 --- a/scripts/tui/src/ovirt/node/config/__init__.py +++ b/scripts/tui/src/ovirt/node/config/__init__.py @@ -1 +1,3 @@ -# And ... +""" +This package is expected to contain modules which handle locale config files. +""" \ No newline at end of file diff --git a/scripts/tui/src/ovirt/node/config/defaults.py b/scripts/tui/src/ovirt/node/config/defaults.py new file mode 100644 index 0000000..be2c180 --- /dev/null +++ b/scripts/tui/src/ovirt/node/config/defaults.py @@ -0,0 +1,294 @@ +#!/usr/bin/python +# +# model.py - Copyright (C) 2012 Red Hat, Inc. +# Written by Fabian Deutsch <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +""" +Classes and functions related to model of the configuration of oVirt Node. + +Node is writing it's configuration into one central configuration file +(OVIRT_NODE_DEFAULTS_FILENAME) afterwards all actual configurations files are +created based on this file. This module provides an high level to this model. + +There are classes for all components which can be configured through that +central configuration file. +Each class (for a component) can have a configure and apply_config method. Look +at the CentralNodeConfiguration for more informations. +""" + +import logging +import glob + +import ovirt.node.utils +import ovirt.node.config + +LOGGER = logging.getLogger(__name__) + +OVIRT_NODE_DEFAULTS_FILENAME = "/etc/defaults/ovirt" + + +def defaults(new_dict=None, filename=OVIRT_NODE_DEFAULTS_FILENAME, + remove_empty=False): + """Reads /etc/defaults/ovirt and creates a dictionary + The dict will contain all OVIRT_* entries of the defaults file. + + Args: + new_dict: New values to be used for setting the defaults + filename: The filename to read the defaults from + remove_empty: Remove a key from defaults file, if the new value is None + Returns: + A dict + """ + + aug = ovirt.node.utils.AugeasWrapper() + basepath = "/files/%s/" % filename.strip("/") + if new_dict: + # If values are given, update the file + LOGGER.debug("Updating oVirtNode defaults file '%s': %s %s" % ( + filename, + new_dict, + basepath)) + aug.set_many(new_dict, basepath) + + if remove_empty: + paths_to_be_removed = [p for p, v in new_dict.items() if v is None] + aug.remove_many(paths_to_be_removed, basepath) + + # Retrieve all entries of the default file and return their values + paths = aug.match(basepath + "*") + return aug.get_many(paths, strip_basepath=basepath) + + +def map_and_update_defaults(func): + """ + >>> class Foo(object): + ... keys = None + ... def _map_config_and_update_defaults(self, *args, **kwargs): + ... return kwargs + ... @map_and_update_defaults + ... def meth(self, a, b): + ... assert type(a) is int + ... assert type(b) is int + >>> foo = Foo() + >>> foo.keys = ("OVIRT_A", "OVIRT_B") + >>> foo.meth(1, 2) + {'OVIRT_A': 1, 'OVIRT_B': 2} + """ + def wrapper(self, *args, **kwargs): + new_dict = dict(zip(self.keys, args)) + func(self, *args, **kwargs) + return self._map_config_and_update_defaults(**new_dict) + return wrapper + + +class CentralNodeConfiguration(object): + def __init__(self, keys): + assert type(keys) is tuple, "Keys need to have an order, " + \ + "therefor a tuple expected" + self.keys = keys + + def configure(self, *args, **kwargs): + """This function set's the correct entries in the defaults file for + that specififc subclass. + Is expected to call _map_config_and_update_defaults() + """ + raise NotImplementedError + + def _map_config_and_update_defaults(self, *args, **kwargs): + assert len(args) == 0 + assert (set(self.keys) ^ set(kwargs.keys())) == set() + new_dict = {k.upper(): v for k, v in kwargs.items()} + defaults(new_dict, remove_empty=True) + + def apply_config(self, *args, **kwargs): + """This method updates the to this subclass specififc configuration + files according to the config keys set with configure. + """ + raise NotImplementedError + + def get_config(self): + """Returns the config keys of the current component + """ + items = {} + for key, value in defaults().items(): + if key in self.keys: + items[key] = value + return items + + +class Network(CentralNodeConfiguration): + """Sets network stuff + - OVIRT_BOOTIF + - OVIRT_IP_ADDRESS, OVIRT_IP_NETMASK, OVIRT_IP_GATEWAY + - OVIRT_VLAN + - OVIRT_IPV6 + """ + keys = ("BOOTIF", + "BOOTPROTO", + "IP_ADDRESS", + "IP_NETMASK", + "IP_GATEWAY", + "VLAN") + + @map_and_update_defaults + def configure(self, iface, bootproto, ipaddr=None, netmask=None, gw=None, + vlanid=None): + pass + + +class Nameservers(CentralNodeConfiguration): + keys = ("DNS") + + @map_and_update_defaults + def configure(self, servers): + pass + + + def apply_config(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) + """ + ovirt_config = defaults() + if "OVIRT_DNS" not in ovirt_config: + LOGGER.debug("No DNS server entry in default config") + return + + servers = ovirt_config["OVIRT_DNS"] + if servers is None or servers == "": + LOGGER.debug("No DNS servers configured in default config") + + servers = servers.split(",") + + aug = ovirt.node.utils.AugeasWrapper() + # 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 + ovirt.node.config.network.nameservers(servers) + + # 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) + + ovirt.node.utils.fs.persist_config("/etc/resolv.conf") + + +class Timeservers(CentralNodeConfiguration): + keys = ("NTP") + + @map_and_update_defaults + def configure(self, servers): + pass + + +class Syslog(CentralNodeConfiguration): + keys = ("SYSLOG_SERVER", + "SYSLOG_PORT") + + @map_and_update_defaults + def configure(self, server, port): + pass + + +class Collectd(CentralNodeConfiguration): + keys = ("COLLECTD_SERVER", + "COLLECTD_PORT") + + @map_and_update_defaults + def configure(self, server, port): + pass + + +class RHN(CentralNodeConfiguration): + keys = ("RHN_TYPE", + "RHN_URL", + "RHN_CA_CERT", + "RHN_USERNAME", + "RHN_PASSWORD", + "RHN_PROFILE", + "RHN_ACTIVATIONKEY", + "RHN_ORG", + "RHN_PROXY", + "RHN_PROXYUSER", + "RHN_PROXYPASSWORD") + + @map_and_update_defaults + def configure(self, rhntype, url, ca_cert, username, password, profile, + activationkey, org, proxy, proxyuser, proxypassword): + pass + + +class KDump(CentralNodeConfiguration): + keys = ("KDUMP_NFS", + "KDUMP_SSH") + + @map_and_update_defaults + def configure(self, nfs, ssh): + pass + + +class iSCSI(CentralNodeConfiguration): + keys = ("ISCSI_NODE_NAME", + "ISCSI_TARGET_NAME", + "ISCSI_TARGET_IP", + "ISCSI_TARGET_PORT") + + @map_and_update_defaults + def configure(self, name, target_name, target_host, target_port): + pass + + +class SNMP(CentralNodeConfiguration): + keys = ("SNMP_PASSWORD") + + @map_and_update_defaults + def configure(self, password): + pass + + +class Netconsole(CentralNodeConfiguration): + keys = ("NETCONSOLE_SERVER", + "NETCONSOLE_PORT") + + @map_and_update_defaults + def configure(self, server, port): + pass + + +class CIM(CentralNodeConfiguration): + keys = ("CIM_ENABLED") + + @map_and_update_defaults + def configure(self, enabled): + assert enabled in ["1", "0"] \ No newline at end of file diff --git a/scripts/tui/src/ovirt/node/model.py b/scripts/tui/src/ovirt/node/model.py deleted file mode 100644 index 75bc74b..0000000 --- a/scripts/tui/src/ovirt/node/model.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/python -# -# model.py - Copyright (C) 2012 Red Hat, Inc. -# Written by Fabian Deutsch <[email protected]> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. A copy of the GNU General Public License is -# also available at http://www.gnu.org/copyleft/gpl.html. - -""" -oVirt Node Model functions -""" - -import logging -import glob - -import ovirt.node.utils - -LOGGER = logging.getLogger(__name__) - -OVIRT_NODE_DEFAULTS_FILENAME = "/etc/defaults/ovirt" - - -def defaults(new_dict=None, filename=OVIRT_NODE_DEFAULTS_FILENAME): - """Reads /etc/defaults/ovirt - - Args: - new_dict: New values to be used for setting the defaults - Returns: - A dict - """ - aug = ovirt.node.utils.AugeasWrapper() - basepath = "/files/%s/" % filename.strip("/") - if new_dict: - # If values are given, update the file - aug.set_many(new_dict, basepath + "OVIRT_") - - # Retrieve all entries of the default file and return their values - paths = aug.match(basepath + "*") - return aug.get_many(paths) - - -def configure_networking(iface, bootproto, ipaddr=None, netmask=None, gw=None, - vlanid=None): - """Sets - - OVIRT_BOOTIF - - OVIRT_IP_ADDRESS, OVIRT_IP_NETMASK, OVIRT_IP_GATEWAY - - OVIRT_VLAN - - OVIRT_IPV6 - """ - config = { - "BOOTIF": iface, - "BOOTPROTO": bootproto, - "IP_ADDRESS": ipaddr, - "IP_NETMASK": netmask, - "IP_GATEWAY": gw, - "VLAN": vlanid - } - defaults(config) - # FIXME also remove keys with None value? - - -def configure_nameservers(servers): - """Sets 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) - """ - ovirt_config = defaults() - if "OVIRT_DNS" not in ovirt_config: - LOGGER.debug("No DNS server entry in default config") - return - - servers = ovirt_config["OVIRT_DNS"] - if servers is None or servers == "": - LOGGER.debug("No DNS servers configured in default config") - - servers = servers.split(",") - - aug = ovirt.node.utils.AugeasWrapper() - # 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 - ovirt.node.config.network.nameservers(servers) - - # 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) - - ovirt.node.utils.fs.persist_config("/etc/resolv.conf") - - -def timeservers(servers): - """Sets OVIRT_NTP - - Args: - servers: List of servers (str) - """ - pass - - -def syslog(server, port): - """Sets OVIRT_SYSLOG_{SERVER,PORT} - """ - pass - - -def collectd(server, port): - """Sets OVIRT_COLLECTD_{SERVER,PORT} - """ - pass - - -def rhn(rhntype, url, ca_cert, username, password, profile, activationkey, org, - proxy, proxyuser, proxypassword): - """Sets ... - """ - pass - - -def kdump(nfs, ssh): - """Sets ... - """ - pass - - -def iscsi(name, target_name, target_host, target_port): - """Sets ... - """ - pass - - -def snmp(password): - """Sets ... - """ - pass - - -def netconsole(server, port): - """Sets ... - """ - pass - - -def cim(enabled): - """Sets ... - """ - pass diff --git a/scripts/tui/src/ovirt/node/plugins/kdump_page.py b/scripts/tui/src/ovirt/node/plugins/kdump_page.py index 8d9c205..5c06104 100644 --- a/scripts/tui/src/ovirt/node/plugins/kdump_page.py +++ b/scripts/tui/src/ovirt/node/plugins/kdump_page.py @@ -26,7 +26,6 @@ import ovirt.node.plugins import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/keyboard_page.py b/scripts/tui/src/ovirt/node/plugins/keyboard_page.py index 85b3008..d914b65 100644 --- a/scripts/tui/src/ovirt/node/plugins/keyboard_page.py +++ b/scripts/tui/src/ovirt/node/plugins/keyboard_page.py @@ -24,10 +24,7 @@ import logging import ovirt.node.plugins -import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils -import ovirt.node.utils.network LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/logging_page.py b/scripts/tui/src/ovirt/node/plugins/logging_page.py index baa7407..2f56ff4 100644 --- a/scripts/tui/src/ovirt/node/plugins/logging_page.py +++ b/scripts/tui/src/ovirt/node/plugins/logging_page.py @@ -26,7 +26,6 @@ import ovirt.node.plugins import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/monitoring_page.py b/scripts/tui/src/ovirt/node/plugins/monitoring_page.py index 97b7dcf..2a1ff8e 100644 --- a/scripts/tui/src/ovirt/node/plugins/monitoring_page.py +++ b/scripts/tui/src/ovirt/node/plugins/monitoring_page.py @@ -26,7 +26,6 @@ import ovirt.node.plugins import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/network_page.py b/scripts/tui/src/ovirt/node/plugins/network_page.py index 32ffc82..8302917 100644 --- a/scripts/tui/src/ovirt/node/plugins/network_page.py +++ b/scripts/tui/src/ovirt/node/plugins/network_page.py @@ -26,7 +26,6 @@ import ovirt.node.plugins import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils import ovirt.node.utils.network import ovirt.node.config.network @@ -105,12 +104,6 @@ def _get_nics(self): justify = lambda txt, l: txt.ljust(l)[0:l] - node_nics = [ - ("em1", - "em1 Configured e1000 00:11:22:33:44:55"), - ("p1p6", - "p1p6 Unconfigured bnx2 10:21:32:43:54:65"), - ] node_nics = [] first_nic = None for name, nic in ovirt.node.utils.network.node_nics().items(): @@ -224,16 +217,18 @@ new_servers = [v for k, v in effective_model \ if k.startswith("dns[")] LOGGER.info("Setting new nameservers: %s" % new_servers) - ovirt.node.utils.network.nameservers(new_servers) + model = ovirt.node.config.defaults.Nameservers() + model.configure(new_servers) if "ntp[0]" in effective_changes or \ "ntp[1]" in effective_changes: new_servers = [v for k, v in effective_model \ if k.startswith("ntp[")] LOGGER.info("Setting new timeservers: %s" % new_servers) - ovirt.node.utils.network.timeservers(new_servers) + model = ovirt.node.config.defaults.Timeservers() + model.configure(new_servers) if "nics" in changes: iface = changes["nics"] LOGGER.debug("Opening NIC Details dialog for '%s'" % iface) - return self._build_nic_details_dialog() + return self._build_nic_details_dialog() \ No newline at end of file diff --git a/scripts/tui/src/ovirt/node/plugins/remote_storage_page.py b/scripts/tui/src/ovirt/node/plugins/remote_storage_page.py index 9c23bcd..80c3d2d 100644 --- a/scripts/tui/src/ovirt/node/plugins/remote_storage_page.py +++ b/scripts/tui/src/ovirt/node/plugins/remote_storage_page.py @@ -24,9 +24,7 @@ import logging import ovirt.node.plugins -import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/security_page.py b/scripts/tui/src/ovirt/node/plugins/security_page.py index 681e041..d1aef46 100644 --- a/scripts/tui/src/ovirt/node/plugins/security_page.py +++ b/scripts/tui/src/ovirt/node/plugins/security_page.py @@ -26,7 +26,6 @@ import ovirt.node.plugins import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/snmp_page.py b/scripts/tui/src/ovirt/node/plugins/snmp_page.py index 421fa5f..a0ce026 100644 --- a/scripts/tui/src/ovirt/node/plugins/snmp_page.py +++ b/scripts/tui/src/ovirt/node/plugins/snmp_page.py @@ -26,7 +26,6 @@ import ovirt.node.plugins import ovirt.node.valid import ovirt.node.ui -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/plugins/status_page.py b/scripts/tui/src/ovirt/node/plugins/status_page.py index 8558eb8..e3dd12e 100644 --- a/scripts/tui/src/ovirt/node/plugins/status_page.py +++ b/scripts/tui/src/ovirt/node/plugins/status_page.py @@ -25,7 +25,6 @@ import textwrap import ovirt.node.plugins -import ovirt.node.valid import ovirt.node.ui import ovirt.node.utils as utils import ovirt.node.utils.virt as virt diff --git a/scripts/tui/src/ovirt/node/ui/builder.py b/scripts/tui/src/ovirt/node/ui/builder.py index d2d2446..8129720 100644 --- a/scripts/tui/src/ovirt/node/ui/builder.py +++ b/scripts/tui/src/ovirt/node/ui/builder.py @@ -27,13 +27,8 @@ import logging -import ovirt.node -import ovirt.node.plugins -import ovirt.node.ui import ovirt.node.ui.widgets -import ovirt.node.ui.builder import ovirt.node.exceptions -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/ui/tui.py b/scripts/tui/src/ovirt/node/ui/tui.py index d120d28..f763b68 100644 --- a/scripts/tui/src/ovirt/node/ui/tui.py +++ b/scripts/tui/src/ovirt/node/ui/tui.py @@ -27,13 +27,8 @@ import logging import timeit -import ovirt.node -import ovirt.node.plugins -import ovirt.node.ui import ovirt.node.ui.widgets import ovirt.node.ui.builder -import ovirt.node.exceptions -import ovirt.node.utils LOGGER = logging.getLogger(__name__) diff --git a/scripts/tui/src/ovirt/node/utils/__init__.py b/scripts/tui/src/ovirt/node/utils/__init__.py index e99e546..1ddcd7e 100644 --- a/scripts/tui/src/ovirt/node/utils/__init__.py +++ b/scripts/tui/src/ovirt/node/utils/__init__.py @@ -19,7 +19,11 @@ # also available at http://www.gnu.org/copyleft/gpl.html. """ -Utility functions +Utility functions. +It is aimed that the modules in trhis package display live informations and not +informations based on static config files. +Use the .config package for stuff related to configuration files. +And use the model.py module for oVirt Node's defaults file. """ import logging @@ -92,7 +96,7 @@ values = {} for path in paths: if strip_basepath: - path = path[len(basepath):] + path = path[len(strip_basepath):] values[path] = self.get(path) return values -- To view, visit http://gerrit.ovirt.org/9928 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie04c429322a8bb1dd6ca2e2e92a6e6f20fc3b745 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-node Gerrit-Branch: master Gerrit-Owner: Fabian Deutsch <[email protected]> _______________________________________________ node-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/node-patches
