On Mon, Nov 17, 2014 at 7:56 PM, 'Aaron Karper' via ganeti-devel <[email protected]> wrote: > This is preparing to split ConfigWriter. > > Signed-off-by: Aaron Karper <[email protected]> > --- > Makefile.am | 3 +- > lib/config/__init__.py | 288 > +++++++++++++++++++++---------------------------- > lib/config/utils.py | 80 ++++++++++++++ > 3 files changed, 204 insertions(+), 167 deletions(-) > create mode 100644 lib/config/utils.py > > diff --git a/Makefile.am b/Makefile.am > index e83e33b..9563d32 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -514,7 +514,8 @@ cmdlib_cluster_PYTHON = \ > > config_PYTHON = \ > lib/config/__init__.py \ > - lib/config/temporary_reservations.py > + lib/config/temporary_reservations.py \ > + lib/config/utils.py > > hypervisor_PYTHON = \ > lib/hypervisor/__init__.py \ > diff --git a/lib/config/__init__.py b/lib/config/__init__.py > index 57f6d66..6e7f0fb 100644 > --- a/lib/config/__init__.py > +++ b/lib/config/__init__.py > @@ -52,6 +52,7 @@ import threading > import itertools > > from ganeti.config.temporary_reservations import TemporaryReservationManager > +from ganeti.config.utils import ConfigSync, ConfigManager > > from ganeti import errors > from ganeti import utils > @@ -108,17 +109,6 @@ def GetConfig(ec_id, livelock, **kwargs): > return ConfigWriter(**kwargs) > > > -def _ConfigSync(shared=0): > - """Configuration synchronization decorator. > - > - """ > - def wrap(fn): > - def sync_function(*args, **kwargs): > - with args[0].GetConfigManager(shared): > - return fn(*args, **kwargs) > - return sync_function > - return wrap > - > # job id used for resource management at config upgrade time > _UPGRADE_CONFIG_JID = "jid-cfg-upgrade" > > @@ -164,40 +154,6 @@ def _CheckInstanceDiskIvNames(disks): > return result > > > -class ConfigManager(object): > - """Locks the configuration and exposes it to be read or modified. > - > - """ > - def __init__(self, config_writer, shared=False, forcelock=False): > - assert isinstance(config_writer, ConfigWriter), \ > - "invalid argument: Not a ConfigWriter" > - self._config_writer = config_writer > - self._shared = shared > - self._forcelock = forcelock > - > - def __enter__(self): > - try: > - self._config_writer._OpenConfig(# pylint: disable=W0212 > - self._shared, > - force=self._forcelock) > - except Exception: > - logging.debug("Opening configuration failed") > - try: > - self._config_writer._CloseConfig(False) # pylint: disable=W0212 > - except Exception: # pylint: disable=W0703 > - logging.debug("Closing configuration failed as well") > - raise > - > - def __exit__(self, exc_type, exc_value, traceback): > - # save the configuration, if this was a write opreration that succeeded > - if exc_type is not None: > - logging.debug("Configuration operation failed," > - " the changes will not be saved") > - # pylint: disable=W0212 > - self._config_writer._CloseConfig(not self._shared and exc_type is None) > - return False > - > - > def _UpdateIvNames(base_idx, disks): > """Update the C{iv_name} attribute of disks. > > @@ -263,7 +219,7 @@ class ConfigWriter(object): > """ > return os.path.exists(pathutils.CLUSTER_CONF_FILE) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNdParams(self, node): > """Get the node params populated with cluster defaults. > > @@ -275,7 +231,7 @@ class ConfigWriter(object): > nodegroup = self._UnlockedGetNodeGroup(node.group) > return self._ConfigData().cluster.FillND(node, nodegroup) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNdGroupParams(self, nodegroup): > """Get the node groups params populated with cluster defaults. > > @@ -297,7 +253,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.FillNDGroup(group) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetGroupSshPorts(self): > """Get a map of group UUIDs to SSH ports. > > @@ -312,7 +268,7 @@ class ConfigWriter(object): > port_map[uuid] = port > return port_map > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceDiskParams(self, instance): > """Get the disk params populated with inherit chain. > > @@ -325,7 +281,7 @@ class ConfigWriter(object): > nodegroup = self._UnlockedGetNodeGroup(node.group) > return self._UnlockedGetGroupDiskParams(nodegroup) > > - @_ConfigSync() > + @ConfigSync() > def SetInstanceDiskTemplate(self, inst_uuid, disk_template): > """Set the instance's disk template to the given value. > > @@ -359,7 +315,7 @@ class ConfigWriter(object): > return [self._UnlockedGetDiskInfo(disk_uuid) > for disk_uuid in instance.disks] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceDisks(self, inst_uuid): > """Return the disks' info for the given instance > > @@ -427,7 +383,7 @@ class ConfigWriter(object): > instance.serial_no += 1 > instance.mtime = time.time() > > - @_ConfigSync() > + @ConfigSync() > def AddInstanceDisk(self, inst_uuid, disk, idx=None): > """Add a disk to the config and attach it to instance. > > @@ -487,7 +443,7 @@ class ConfigWriter(object): > del self._ConfigData().disks[disk_uuid] > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync() > + @ConfigSync() > def RemoveInstanceDisk(self, inst_uuid, disk_uuid): > """Detach a disk from an instance and remove it from the config. > > @@ -514,7 +470,7 @@ class ConfigWriter(object): > > return self._ConfigData().disks[disk_uuid] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetDiskInfo(self, disk_uuid): > """Returns information about a disk. > > @@ -562,7 +518,7 @@ class ConfigWriter(object): > all_nodes.discard(instance.primary_node) > return (instance.primary_node, ) + tuple(all_nodes) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceNodes(self, inst_uuid): > """Get all disk-related nodes for an instance. > > @@ -584,7 +540,7 @@ class ConfigWriter(object): > all_nodes.discard(instance.primary_node) > return tuple(all_nodes) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceSecondaryNodes(self, inst_uuid): > """Get the list of secondary nodes. > > @@ -641,7 +597,7 @@ class ConfigWriter(object): > instance.primary_node) > return ret > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceLVsByNode(self, inst_uuid, lvmap=None): > """Provide a mapping of node to LVs a given instance owns. > > @@ -650,7 +606,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetInstanceLVsByNode(inst_uuid, lvmap=lvmap) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetGroupDiskParams(self, group): > """Get the disk params populated with inherit chain. > > @@ -673,7 +629,7 @@ class ConfigWriter(object): > assert isinstance(data, dict), "Not a dictionary: " + str(data) > return data > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetPotentialMasterCandidates(self): > """Gets the list of node names of potential master candidates. > > @@ -827,7 +783,7 @@ class ConfigWriter(object): > existing = self._AllIDs(include_temporary=False) > return self._temporary_ids.Generate(existing, utils.NewUUID, ec_id) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GenerateUniqueID(self, ec_id): > """Generate an unique ID. > > @@ -1214,7 +1170,7 @@ class ConfigWriter(object): > feedback_fn(errmsg) > return config_errors > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def VerifyConfig(self): > """Verify function. > > @@ -1227,7 +1183,7 @@ class ConfigWriter(object): > """ > return self._UnlockedVerifyConfig() > > - @_ConfigSync() > + @ConfigSync() > def AddTcpUdpPort(self, port): > """Adds a new port to the available port pool. > > @@ -1241,14 +1197,14 @@ class ConfigWriter(object): > > self._ConfigData().cluster.tcpudp_port_pool.add(port) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetPortList(self): > """Returns a copy of the current port list. > > """ > return self._ConfigData().cluster.tcpudp_port_pool.copy() > > - @_ConfigSync() > + @ConfigSync() > def AllocatePort(self): > """Allocate a port. > > @@ -1269,7 +1225,7 @@ class ConfigWriter(object): > self._ConfigData().cluster.highest_used_port = port > return port > > - @_ConfigSync() > + @ConfigSync() > def ComputeDRBDMap(self): > """Compute the used DRBD minor/nodes. > > @@ -1330,7 +1286,7 @@ class ConfigWriter(object): > if not self._offline: > self._wconfd.ReleaseDRBDMinors(inst_uuid) > > - @_ConfigSync() > + @ConfigSync() > def ReleaseDRBDMinors(self, inst_uuid): > """Release temporary drbd minors allocated for a given instance. > > @@ -1347,7 +1303,7 @@ class ConfigWriter(object): > """ > self._UnlockedReleaseDRBDMinors(inst_uuid) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetConfigVersion(self): > """Get the configuration version. > > @@ -1356,7 +1312,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().version > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetClusterName(self): > """Get cluster name. > > @@ -1365,7 +1321,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.cluster_name > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterNode(self): > """Get the UUID of the master node for this cluster. > > @@ -1374,7 +1330,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.master_node > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterNodeName(self): > """Get the hostname of the master node for this cluster. > > @@ -1383,7 +1339,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNodeName(self._ConfigData().cluster.master_node) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterNodeInfo(self): > """Get the master node information for this cluster. > > @@ -1393,7 +1349,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNodeInfo(self._ConfigData().cluster.master_node) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterIP(self): > """Get the IP of the master node for this cluster. > > @@ -1402,56 +1358,56 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.master_ip > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterNetdev(self): > """Get the master network device for this cluster. > > """ > return self._ConfigData().cluster.master_netdev > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterNetmask(self): > """Get the netmask of the master node for this cluster. > > """ > return self._ConfigData().cluster.master_netmask > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetUseExternalMipScript(self): > """Get flag representing whether to use the external master IP setup > script. > > """ > return self._ConfigData().cluster.use_external_mip_script > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetFileStorageDir(self): > """Get the file storage dir for this cluster. > > """ > return self._ConfigData().cluster.file_storage_dir > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetSharedFileStorageDir(self): > """Get the shared file storage dir for this cluster. > > """ > return self._ConfigData().cluster.shared_file_storage_dir > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetGlusterStorageDir(self): > """Get the Gluster storage dir for this cluster. > > """ > return self._ConfigData().cluster.gluster_storage_dir > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetHypervisorType(self): > """Get the hypervisor type for this cluster. > > """ > return self._ConfigData().cluster.enabled_hypervisors[0] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetRsaHostKey(self): > """Return the rsa hostkey from the config. > > @@ -1461,7 +1417,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.rsahostkeypub > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetDsaHostKey(self): > """Return the dsa hostkey from the config. > > @@ -1471,14 +1427,14 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.dsahostkeypub > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetDefaultIAllocator(self): > """Get the default instance allocator for this cluster. > > """ > return self._ConfigData().cluster.default_iallocator > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetDefaultIAllocatorParameters(self): > """Get the default instance allocator parameters for this cluster. > > @@ -1488,7 +1444,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.default_iallocator_params > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetPrimaryIPFamily(self): > """Get cluster primary ip family. > > @@ -1497,7 +1453,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.primary_ip_family > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterNetworkParameters(self): > """Get network parameters of the master node. > > @@ -1513,7 +1469,7 @@ class ConfigWriter(object): > > return result > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstallImage(self): > """Get the install image location > > @@ -1523,7 +1479,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.install_image > > - @_ConfigSync() > + @ConfigSync() > def SetInstallImage(self, install_image): > """Set the install image location > > @@ -1533,7 +1489,7 @@ class ConfigWriter(object): > """ > self._ConfigData().cluster.install_image = install_image > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceCommunicationNetwork(self): > """Get cluster instance communication network > > @@ -1544,7 +1500,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.instance_communication_network > > - @_ConfigSync() > + @ConfigSync() > def SetInstanceCommunicationNetwork(self, network_name): > """Set cluster instance communication network > > @@ -1555,7 +1511,7 @@ class ConfigWriter(object): > """ > self._ConfigData().cluster.instance_communication_network = network_name > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetZeroingImage(self): > """Get the zeroing image location > > @@ -1565,7 +1521,7 @@ class ConfigWriter(object): > """ > return self._config_data.cluster.zeroing_image > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetCompressionTools(self): > """Get cluster compression tools > > @@ -1576,7 +1532,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster.compression_tools > > - @_ConfigSync() > + @ConfigSync() > def SetCompressionTools(self, tools): > """Set cluster compression tools > > @@ -1587,7 +1543,7 @@ class ConfigWriter(object): > """ > self._ConfigData().cluster.compression_tools = tools > > - @_ConfigSync() > + @ConfigSync() > def AddNodeGroup(self, group, ec_id, check_uuid=True): > """Add a node group to the configuration. > > @@ -1635,7 +1591,7 @@ class ConfigWriter(object): > self._ConfigData().nodegroups[group.uuid] = group > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync() > + @ConfigSync() > def RemoveNodeGroup(self, group_uuid): > """Remove a node group from the configuration. > > @@ -1678,7 +1634,7 @@ class ConfigWriter(object): > raise errors.OpPrereqError("Node group '%s' not found" % target, > errors.ECODE_NOENT) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def LookupNodeGroup(self, target): > """Lookup a node group's UUID. > > @@ -1706,7 +1662,7 @@ class ConfigWriter(object): > > return self._ConfigData().nodegroups[uuid] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeGroup(self, uuid): > """Lookup a node group. > > @@ -1724,14 +1680,14 @@ class ConfigWriter(object): > """ > return dict(self._ConfigData().nodegroups) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetAllNodeGroupsInfo(self): > """Get the configuration of all node groups. > > """ > return self._UnlockedGetAllNodeGroupsInfo() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetAllNodeGroupsInfoDict(self): > """Get the configuration of all node groups expressed as a dictionary of > dictionaries. > @@ -1740,14 +1696,14 @@ class ConfigWriter(object): > return dict(map(lambda (uuid, ng): (uuid, ng.ToDict()), > self._UnlockedGetAllNodeGroupsInfo().items())) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeGroupList(self): > """Get a list of node groups. > > """ > return self._ConfigData().nodegroups.keys() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeGroupMembersByNodes(self, nodes): > """Get nodes which are member in the same nodegroups as the given nodes. > > @@ -1758,7 +1714,7 @@ class ConfigWriter(object): > for member_uuid in > self._UnlockedGetNodeGroup(ngfn(node_uuid)).members) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMultiNodeGroupInfo(self, group_uuids): > """Get the configuration of multiple node groups. > > @@ -1857,7 +1813,7 @@ class ConfigWriter(object): > instance.mtime = time.time() > return instance > > - @_ConfigSync() > + @ConfigSync() > def MarkInstanceUp(self, inst_uuid): > """Mark the instance status to up in the config. > > @@ -1870,7 +1826,7 @@ class ConfigWriter(object): > return self._SetInstanceStatus(inst_uuid, constants.ADMINST_UP, True, > constants.ADMIN_SOURCE) > > - @_ConfigSync() > + @ConfigSync() > def MarkInstanceOffline(self, inst_uuid): > """Mark the instance status to down in the config. > > @@ -1883,7 +1839,7 @@ class ConfigWriter(object): > return self._SetInstanceStatus(inst_uuid, constants.ADMINST_OFFLINE, > False, > constants.ADMIN_SOURCE) > > - @_ConfigSync() > + @ConfigSync() > def RemoveInstance(self, inst_uuid): > """Remove the instance from the configuration. > > @@ -1910,7 +1866,7 @@ class ConfigWriter(object): > del self._ConfigData().instances[inst_uuid] > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync() > + @ConfigSync() > def RenameInstance(self, inst_uuid, new_name): > """Rename an instance. > > @@ -1937,7 +1893,7 @@ class ConfigWriter(object): > # Force update of ssconf files > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync() > + @ConfigSync() > def MarkInstanceDown(self, inst_uuid): > """Mark the status of an instance to down in the configuration. > > @@ -1951,7 +1907,7 @@ class ConfigWriter(object): > return self._SetInstanceStatus(inst_uuid, constants.ADMINST_DOWN, None, > constants.ADMIN_SOURCE) > > - @_ConfigSync() > + @ConfigSync() > def MarkInstanceUserDown(self, inst_uuid): > """Mark the status of an instance to user down in the configuration. > > @@ -1963,7 +1919,7 @@ class ConfigWriter(object): > self._SetInstanceStatus(inst_uuid, constants.ADMINST_DOWN, None, > constants.USER_SOURCE) > > - @_ConfigSync() > + @ConfigSync() > def MarkInstanceDisksActive(self, inst_uuid): > """Mark the status of instance disks active. > > @@ -1973,7 +1929,7 @@ class ConfigWriter(object): > """ > return self._SetInstanceStatus(inst_uuid, None, True, None) > > - @_ConfigSync() > + @ConfigSync() > def MarkInstanceDisksInactive(self, inst_uuid): > """Mark the status of instance disks inactive. > > @@ -1991,7 +1947,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().instances.keys() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceList(self): > """Get the list of instances. > > @@ -2027,7 +1983,7 @@ class ConfigWriter(object): > > return self._ConfigData().instances[inst_uuid] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceInfo(self, inst_uuid): > """Returns information about an instance. > > @@ -2042,7 +1998,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetInstanceInfo(inst_uuid) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceNodeGroups(self, inst_uuid, primary_only=False): > """Returns set of node group UUIDs for instance's nodes. > > @@ -2061,7 +2017,7 @@ class ConfigWriter(object): > return frozenset(self._UnlockedGetNodeInfo(node_uuid).group > for node_uuid in nodes) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceNetworks(self, inst_uuid): > """Returns set of network UUIDs for instance's nics. > > @@ -2079,7 +2035,7 @@ class ConfigWriter(object): > > return frozenset(networks) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMultiInstanceInfo(self, inst_uuids): > """Get the configuration of multiple instances. > > @@ -2092,7 +2048,7 @@ class ConfigWriter(object): > """ > return [(uuid, self._UnlockedGetInstanceInfo(uuid)) for uuid in > inst_uuids] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMultiInstanceInfoByName(self, inst_names): > """Get the configuration of multiple instances. > > @@ -2109,7 +2065,7 @@ class ConfigWriter(object): > result.append((instance.uuid, instance)) > return result > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetAllInstancesInfo(self): > """Get the configuration of all instances. > > @@ -2125,7 +2081,7 @@ class ConfigWriter(object): > for inst_uuid in self._UnlockedGetInstanceList()]) > return my_dict > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstancesInfoByFilter(self, filter_fn): > """Get instance configuration with a filter. > > @@ -2141,7 +2097,7 @@ class ConfigWriter(object): > for (uuid, inst) in self._ConfigData().instances.items() > if filter_fn(inst)) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceInfoByName(self, inst_name): > """Get the L{objects.Instance} object for a named instance. > > @@ -2165,7 +2121,7 @@ class ConfigWriter(object): > raise errors.OpExecError("Unknown instance: %s" % inst_uuid) > return inst_info.name > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceName(self, inst_uuid): > """Gets the instance name for the passed instance. > > @@ -2177,7 +2133,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetInstanceName(inst_uuid) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetInstanceNames(self, inst_uuids): > """Gets the instance names for the passed list of nodes. > > @@ -2189,7 +2145,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetInstanceNames(inst_uuids) > > - @_ConfigSync() > + @ConfigSync() > def SetInstancePrimaryNode(self, inst_uuid, target_node_uuid): > """Sets the primary node of an existing instance > > @@ -2201,7 +2157,7 @@ class ConfigWriter(object): > """ > self._UnlockedGetInstanceInfo(inst_uuid).primary_node = target_node_uuid > > - @_ConfigSync() > + @ConfigSync() > def SetDiskNodes(self, disk_uuid, nodes): > """Sets the nodes of an existing disk > > @@ -2234,7 +2190,7 @@ class ConfigWriter(object): > self._ConfigData().nodes[node.uuid] = node > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync() > + @ConfigSync() > def AddNode(self, node, ec_id): > """Add a node to the configuration. > > @@ -2244,7 +2200,7 @@ class ConfigWriter(object): > """ > self._UnlockedAddNode(node, ec_id) > > - @_ConfigSync() > + @ConfigSync() > def RemoveNode(self, node_uuid): > """Remove a node from the configuration. > > @@ -2291,7 +2247,7 @@ class ConfigWriter(object): > > return self._ConfigData().nodes[node_uuid] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeInfo(self, node_uuid): > """Get the configuration of a node, as stored in the config. > > @@ -2305,7 +2261,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNodeInfo(node_uuid) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeInstances(self, node_uuid): > """Get the instances of a node, as stored in the config. > > @@ -2324,7 +2280,7 @@ class ConfigWriter(object): > sec.append(inst.uuid) > return (pri, sec) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeGroupInstances(self, uuid, primary_only=False): > """Get the instances of a node group. > > @@ -2357,7 +2313,7 @@ class ConfigWriter(object): > result += "%s=%s\n" % (key, hvparams[key]) > return result > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetHvparamsString(self, hvname): > """Return the hypervisor parameters of the given hypervisor. > > @@ -2381,7 +2337,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().nodes.keys() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeList(self): > """Return the list of nodes which are in the configuration. > > @@ -2396,14 +2352,14 @@ class ConfigWriter(object): > for node in self._UnlockedGetNodeList()] > return [node.uuid for node in all_nodes if not node.offline] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetOnlineNodeList(self): > """Return the list of nodes which are online. > > """ > return self._UnlockedGetOnlineNodeList() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetVmCapableNodeList(self): > """Return the list of nodes which are not vm capable. > > @@ -2412,7 +2368,7 @@ class ConfigWriter(object): > for node in self._UnlockedGetNodeList()] > return [node.uuid for node in all_nodes if node.vm_capable] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNonVmCapableNodeList(self): > """Return the list of nodes' uuids which are not vm capable. > > @@ -2421,7 +2377,7 @@ class ConfigWriter(object): > for node in self._UnlockedGetNodeList()] > return [node.uuid for node in all_nodes if not node.vm_capable] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNonVmCapableNodeNameList(self): > """Return the list of nodes' names which are not vm capable. > > @@ -2430,7 +2386,7 @@ class ConfigWriter(object): > for node in self._UnlockedGetNodeList()] > return [node.name for node in all_nodes if not node.vm_capable] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMultiNodeInfo(self, node_uuids): > """Get the configuration of multiple nodes. > > @@ -2452,7 +2408,7 @@ class ConfigWriter(object): > return dict([(node_uuid, self._UnlockedGetNodeInfo(node_uuid)) > for node_uuid in self._UnlockedGetNodeList()]) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetAllNodesInfo(self): > """Get the configuration of all nodes. > > @@ -2469,7 +2425,7 @@ class ConfigWriter(object): > return node > return None > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeInfoByName(self, node_name): > """Get the L{objects.Node} object for a named node. > > @@ -2481,7 +2437,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNodeInfoByName(node_name) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeGroupInfoByName(self, nodegroup_name): > """Get the L{objects.NodeGroup} object for a named node group. > > @@ -2507,7 +2463,7 @@ class ConfigWriter(object): > else: > raise errors.ProgrammerError("Can't handle node spec '%s'" % node_spec) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeName(self, node_spec): > """Gets the node name for the passed node. > > @@ -2522,7 +2478,7 @@ class ConfigWriter(object): > def _UnlockedGetNodeNames(self, node_specs): > return [self._UnlockedGetNodeName(node_spec) for node_spec in node_specs] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeNames(self, node_specs): > """Gets the node names for the passed list of nodes. > > @@ -2534,7 +2490,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNodeNames(node_specs) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNodeGroupsFromNodes(self, node_uuids): > """Returns groups for a list of nodes. > > @@ -2556,7 +2512,7 @@ class ConfigWriter(object): > return [node.uuid for node in self._ConfigData().nodes.values() > if node.master_candidate] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterCandidateUuids(self): > """Get the list of UUIDs of master candidates. > > @@ -2586,7 +2542,7 @@ class ConfigWriter(object): > mc_should = min(mc_max, self._ConfigData().cluster.candidate_pool_size) > return (mc_now, mc_should, mc_max) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMasterCandidateStats(self, exceptions=None): > """Get the number of current and maximum possible candidates. > > @@ -2600,7 +2556,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetMasterCandidateStats(exceptions) > > - @_ConfigSync() > + @ConfigSync() > def MaintainCandidatePool(self, exception_node_uuids): > """Try to grow the candidate pool to the desired size. > > @@ -2664,7 +2620,7 @@ class ConfigWriter(object): > else: > nodegroup_obj.members.remove(node.uuid) > > - @_ConfigSync() > + @ConfigSync() > def AssignGroupNodes(self, mods): > """Changes the group of a number of nodes. > > @@ -3086,21 +3042,21 @@ class ConfigWriter(object): > " values: %s" % err) > return ssconf_values > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetSsconfValues(self): > """Wrapper using lock around _UnlockedGetSsconf(). > > """ > return self._UnlockedGetSsconfValues() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetVGName(self): > """Return the volume group name. > > """ > return self._ConfigData().cluster.volume_group_name > > - @_ConfigSync() > + @ConfigSync() > def SetVGName(self, vg_name): > """Set the volume group name. > > @@ -3108,14 +3064,14 @@ class ConfigWriter(object): > self._ConfigData().cluster.volume_group_name = vg_name > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetDRBDHelper(self): > """Return DRBD usermode helper. > > """ > return self._ConfigData().cluster.drbd_usermode_helper > > - @_ConfigSync() > + @ConfigSync() > def SetDRBDHelper(self, drbd_helper): > """Set DRBD usermode helper. > > @@ -3123,14 +3079,14 @@ class ConfigWriter(object): > self._ConfigData().cluster.drbd_usermode_helper = drbd_helper > self._ConfigData().cluster.serial_no += 1 > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetMACPrefix(self): > """Return the mac prefix. > > """ > return self._ConfigData().cluster.mac_prefix > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetClusterInfo(self): > """Returns information about the cluster > > @@ -3140,14 +3096,14 @@ class ConfigWriter(object): > """ > return self._ConfigData().cluster > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def HasAnyDiskOfType(self, dev_type): > """Check if in there is at disk of the given type in the configuration. > > """ > return self._ConfigData().HasAnyDiskOfType(dev_type) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetDetachedConfig(self): > """Returns a detached version of a ConfigManager, which represents > a read-only snapshot of the configuration at this particular time. > @@ -3155,7 +3111,7 @@ class ConfigWriter(object): > """ > return DetachedConfig(self._ConfigData()) > > - @_ConfigSync() > + @ConfigSync() > def Update(self, target, feedback_fn, ec_id=None): > """Notify function to be called after updates. > > @@ -3240,7 +3196,7 @@ class ConfigWriter(object): > def DropECReservations(self, ec_id): > self._UnlockedDropECReservations(ec_id) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetAllNetworksInfo(self): > """Get configuration info of all the networks. > > @@ -3255,7 +3211,7 @@ class ConfigWriter(object): > """ > return self._ConfigData().networks.keys() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNetworkList(self): > """Get the list of networks. > > @@ -3264,7 +3220,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNetworkList() > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNetworkNames(self): > """Get a list of network names > > @@ -3284,7 +3240,7 @@ class ConfigWriter(object): > > return self._ConfigData().networks[uuid] > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetNetwork(self, uuid): > """Returns information about a network. > > @@ -3298,7 +3254,7 @@ class ConfigWriter(object): > """ > return self._UnlockedGetNetwork(uuid) > > - @_ConfigSync() > + @ConfigSync() > def AddNetwork(self, net, ec_id, check_uuid=True): > """Add a network to the configuration. > > @@ -3344,7 +3300,7 @@ class ConfigWriter(object): > raise errors.OpPrereqError("Network '%s' not found" % target, > errors.ECODE_NOENT) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def LookupNetwork(self, target): > """Lookup a network's UUID. > > @@ -3358,7 +3314,7 @@ class ConfigWriter(object): > """ > return self._UnlockedLookupNetwork(target) > > - @_ConfigSync() > + @ConfigSync() > def RemoveNetwork(self, network_uuid): > """Remove a network from the configuration. > > @@ -3393,14 +3349,14 @@ class ConfigWriter(object): > > return netparams > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetGroupNetParams(self, net_uuid, node_uuid): > """Locking wrapper of _UnlockedGetGroupNetParams() > > """ > return self._UnlockedGetGroupNetParams(net_uuid, node_uuid) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def CheckIPInNodeGroup(self, ip, node_uuid): > """Check IP uniqueness in nodegroup. > > @@ -3428,14 +3384,14 @@ class ConfigWriter(object): > > return (None, None) > > - @_ConfigSync(shared=1) > + @ConfigSync(shared=1) > def GetCandidateCerts(self): > """Returns the candidate certificate map. > > """ > return self._ConfigData().cluster.candidate_certs > > - @_ConfigSync() > + @ConfigSync() > def AddNodeToCandidateCerts(self, node_uuid, cert_digest, > info_fn=logging.info, warn_fn=logging.warn): > """Adds an entry to the candidate certificate map. > @@ -3464,7 +3420,7 @@ class ConfigWriter(object): > % node_uuid) > cluster.candidate_certs[node_uuid] = cert_digest > > - @_ConfigSync() > + @ConfigSync() > def RemoveNodeFromCandidateCerts(self, node_uuid, > warn_fn=logging.warn): > """Removes the entry of the given node in the certificate map. > diff --git a/lib/config/utils.py b/lib/config/utils.py > new file mode 100644 > index 0000000..61a1d70 > --- /dev/null > +++ b/lib/config/utils.py > @@ -0,0 +1,80 @@ > +# > +# > + > +# Copyright (C) 2014 Google Inc. > +# All rights reserved. > +# > +# Redistribution and use in source and binary forms, with or without > +# modification, are permitted provided that the following conditions are > +# met: > +# > +# 1. Redistributions of source code must retain the above copyright notice, > +# this list of conditions and the following disclaimer. > +# > +# 2. Redistributions in binary form must reproduce the above copyright > +# notice, this list of conditions and the following disclaimer in the > +# documentation and/or other materials provided with the distribution. > +# > +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR > +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF > +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING > +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS > +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + > + > +"""Utilities used by the config module.""" > + > + > +import logging > + > + > +def ConfigSync(shared=0): > + """Configuration synchronization decorator. > + > + """ > + def wrap(fn): > + def sync_function(*args, **kwargs): > + with args[0].GetConfigManager(shared): > + return fn(*args, **kwargs) > + return sync_function > + return wrap > + > + > +class ConfigManager(object): > + """Locks the configuration and exposes it to be read or modified. > + > + """ > + def __init__(self, config_writer, shared=False, forcelock=False): > + assert hasattr(config_writer, '_ConfigData'), \ > + "invalid argument: Not a ConfigWriter" > + self._config_writer = config_writer > + self._shared = shared > + self._forcelock = forcelock > + > + def __enter__(self): > + try: > + self._config_writer._OpenConfig(# pylint: disable=W0212 > + self._shared, > + force=self._forcelock) > + except Exception: > + logging.debug("Opening configuration failed") > + try: > + self._config_writer._CloseConfig(False) # pylint: disable=W0212 > + except Exception: # pylint: disable=W0703 > + logging.debug("Closing configuration failed as well") > + raise > + > + def __exit__(self, exc_type, exc_value, traceback): > + # save the configuration, if this was a write opreration that succeeded > + if exc_type is not None: > + logging.debug("Configuration operation failed," > + " the changes will not be saved") > + # pylint: disable=W0212 > + self._config_writer._CloseConfig(not self._shared and exc_type is None) > + return False > -- > 2.1.0.rc2.206.gedb03e5 >
LGTM, thanks. Michele -- Google Germany GmbH Dienerstr. 12 80331 München Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores
