primary_ip_version=None, ipolicy=None,
prealloc_wipe_disks=False, use_external_mip_script=False,
hv_state=None, disk_state=None, enabled_disk_templates=None,
- zeroing_image=None):
+ zeroing_image=None, compression_tools=None):
"""Initialise the cluster.
@type candidate_pool_size: int
now = time.time()
+ if compression_tools is not None:
+ cluster.CheckCompressionTools(compression_tools)
+
# init of cluster config file
cluster_config = objects.Cluster(
serial_no=1,
candidate_certs=candidate_certs,
osparams={},
osparams_private_cluster={},
- zeroing_image=zeroing_image
+ zeroing_image=zeroing_image,
+ compression_tools=compression_tools
)
master_node_config = objects.Node(name=hostname.name,
primary_ip=hostname.ip,
"CLUSTER_DOMAIN_SECRET_OPT",
"CONFIRM_OPT",
"CP_SIZE_OPT",
+ "COMPRESSION_TOOLS_OPT",
"DEBUG_OPT",
"DEBUG_SIMERR_OPT",
"DISKIDX_OPT",
type="string",
help="Set the network name for instance communication")
+COMPRESSION_TOOLS_OPT = \
+ cli_option("--compression-tools",
+ dest="compression_tools", type="string", default=None,
+ help="Comma-separated list of compression tools which are"
+ " allowed to be used by Ganeti in various operations")
+
VG_NAME_OPT = cli_option("--vg-name", dest="vg_name",
help=("Enables LVM and specifies the volume group"
" name (cluster-wide) for disk allocation"
else:
zeroing_image = ""
+ compression_tools = _GetCompressionTools(opts)
+
default_ialloc_params = opts.default_iallocator_params
bootstrap.InitCluster(cluster_name=args[0],
secondary_ip=opts.secondary_ip,
hv_state=hv_state,
disk_state=disk_state,
enabled_disk_templates=enabled_disk_templates,
- zeroing_image=zeroing_image
+ zeroing_image=zeroing_image,
+ compression_tools=compression_tools
)
op = opcodes.OpClusterPostInit()
SubmitOpCode(op, opts=opts)
("instance communication network",
result["instance_communication_network"]),
("zeroing image", result["zeroing_image"]),
+ ("compression tools", result["compression_tools"]),
]),
("Default node parameters",
return drbd_helper
+def _GetCompressionTools(opts):
+ """Determine the list of custom compression tools.
+
+ """
+ if opts.compression_tools:
+ return opts.compression_tools.split(",")
+ elif opts.compression_tools is None:
+ return None # To note the parameter was not provided
+ else:
+ return constants.IEC_DEFAULT_TOOLS # Resetting to default
+
+
def SetClusterParams(opts, args):
"""Modify the cluster.
opts.file_storage_dir is not None or
opts.instance_communication_network is not None or
opts.zeroing_image is not None or
- opts.shared_file_storage_dir is not None):
+ opts.shared_file_storage_dir is not None or
+ opts.compression_tools is not None):
ToStderr("Please give at least one of the parameters.")
return 1
hv_state = dict(opts.hv_state)
+ compression_tools = _GetCompressionTools(opts)
+
op = opcodes.OpClusterSetParams(
vg_name=vg_name,
drbd_helper=drbd_helper,
instance_communication_network=opts.instance_communication_network,
zeroing_image=opts.zeroing_image,
shared_file_storage_dir=opts.shared_file_storage_dir,
+ compression_tools=compression_tools
)
return base.GetResult(None, opts, SubmitOrSend(op, opts))
PRIMARY_IP_VERSION_OPT, PREALLOC_WIPE_DISKS_OPT, NODE_PARAMS_OPT,
GLOBAL_SHARED_FILEDIR_OPT, USE_EXTERNAL_MIP_SCRIPT, DISK_PARAMS_OPT,
HV_STATE_OPT, DISK_STATE_OPT, ENABLED_DISK_TEMPLATES_OPT,
- IPOLICY_STD_SPECS_OPT, GLOBAL_GLUSTER_FILEDIR_OPT, ZEROING_IMAGE_OPT]
+ IPOLICY_STD_SPECS_OPT, GLOBAL_GLUSTER_FILEDIR_OPT, ZEROING_IMAGE_OPT,
+ COMPRESSION_TOOLS_OPT]
+ INSTANCE_POLICY_OPTS + SPLIT_ISPECS_OPTS,
"[opts...] <cluster_name>", "Initialises a new cluster configuration"),
"destroy": (
SUBMIT_OPTS +
[ENABLED_DISK_TEMPLATES_OPT, IPOLICY_STD_SPECS_OPT, MODIFY_ETCHOSTS_OPT] +
INSTANCE_POLICY_OPTS +
- [GLOBAL_FILEDIR_OPT, GLOBAL_SHARED_FILEDIR_OPT, ZEROING_IMAGE_OPT],
+ [GLOBAL_FILEDIR_OPT, GLOBAL_SHARED_FILEDIR_OPT, ZEROING_IMAGE_OPT,
+ COMPRESSION_TOOLS_OPT],
"[opts...]",
"Alters the parameters of the cluster"),
"renew-crypto": (
"blacklisted_os": cluster.blacklisted_os,
"enabled_disk_templates": cluster.enabled_disk_templates,
"instance_communication_network": cluster.instance_communication_network,
+ "compression_tools": cluster.compression_tools,
}
return result
constants.DT_SHARED_FILE)
+def CheckCompressionTools(tools):
+ """Check whether the provided compression tools look like executables.
+
+ @type tools: list of string
+ @param tools: The tools provided as opcode input
+
+ """
+ regex = re.compile('^[-_a-zA-Z0-9]+$')
+ illegal_tools = [t for t in tools if not regex.match(t)]
+
+ if illegal_tools:
+ raise errors.OpPrereqError(
+ "The tools '%s' contain illegal characters: only alphanumeric values,"
+ " dashes, and underscores are allowed" % ", ".join(illegal_tools)
+ )
+
+ if constants.IEC_GZIP not in tools:
+ raise errors.OpPrereqError("For compatibility reasons, the %s utility must"
+ " be present among the compression tools" %
+ constants.IEC_GZIP)
+
+ if constants.IEC_NONE in tools:
+ raise errors.OpPrereqError("%s is a reserved value used for no compression,"
+ " and cannot be used as the name of a tool" %
+ constants.IEC_NONE)
+
+
class LUClusterSetParams(LogicalUnit):
"""Change the parameters of the cluster.
network = self.cfg.GetNetwork(network_uuid)
self._CheckInstanceCommunicationNetwork(network, self.LogWarning)
+ if self.op.compression_tools:
+ CheckCompressionTools(self.op.compression_tools)
+
def _BuildOSParams(self, cluster):
"Calculate the new OS parameters for this operation."
result.Warn("Could not re-enable the master ip on the master,"
" please restart manually", self.LogWarning)
+ if self.op.compression_tools is not None:
+ self.cfg.SetCompressionTools(self.op.compression_tools)
+
network_name = self.op.instance_communication_network
if network_name is not None:
return self._ModifyInstanceCommunicationNetwork(self.cfg,
"""
return self._config_data.cluster.zeroing_image
+ @_ConfigSync(shared=1)
+ def GetCompressionTools(self):
+ """Get cluster compression tools
+
+ @rtype: list of string
+ @return: a list of tools that are cleared for use in this cluster for the
+ purpose of compressing data
+
+ """
+ return self._ConfigData().cluster.compression_tools
+
+ @_ConfigSync()
+ def SetCompressionTools(self, tools):
+ """Set cluster compression tools
+
+ @type tools: list of string
+ @param tools: a list of tools that are cleared for use in this cluster for
+ the purpose of compressing data
+
+ """
+ self._ConfigData().cluster.compression_tools = tools
+
@_ConfigSync()
def AddNodeGroup(self, group, ec_id, check_uuid=True):
"""Add a node group to the configuration.
"candidate_certs",
"max_running_jobs",
"instance_communication_network",
- "zeroing_image"
+ "zeroing_image",
+ "compression_tools",
] + _TIMESTAMPS + _UUID
def UpgradeConfig(self):
if self.instance_communication_network is None:
self.instance_communication_network = ""
+ if self.compression_tools is None:
+ self.compression_tools = constants.IEC_DEFAULT_TOOLS
+
@property
def primary_hypervisor(self):
"""The first hypervisor is the primary.
iecAll :: [String]
iecAll = [iecGzip, iecGzipFast, iecGzipSlow, iecLzop, iecNone]
+iecDefaultTools :: [String]
+iecDefaultTools = [iecGzip, iecGzipFast, iecGzipSlow]
+
iecCompressionUtilities :: Map String String
iecCompressionUtilities =
Map.fromList
, simpleField "max_running_jobs" [t| Int |]
, simpleField "instance_communication_network" [t| String |]
, simpleField "zeroing_image" [t| String |]
+ , simpleField "compression_tools" [t| [String] |]
]
++ timeStampFields
++ uuidFields
, pClusterGlusterStorageDir
, pInstanceCommunicationNetwork
, pZeroingImage
+ , pCompressionTools
],
[])
, ("OpClusterRedistConf",
, pClusterGlusterStorageDir
, pInstanceCommunicationNetwork
, pZeroingImage
+ , pCompressionTools
, pVgName
, pEnabledHypervisors
, pHypervisor
pZeroingImage =
optionalStringField "zeroing_image"
+-- | The additional tools that can be used to compress data in transit
+pCompressionTools :: Field
+pCompressionTools =
+ withDoc "List of enabled compression tools" . optionalField $
+ simpleField "compression_tools" [t| [NonEmptyString] |]
+
-- | Volume group name.
pVgName :: Field
pVgName =
, ("instance_communication_network",
showJSON (clusterInstanceCommunicationNetwork cluster))
, ("zeroing_image", showJSON $ clusterZeroingImage cluster)
+ , ("compression_tools",
+ showJSON $ clusterCompressionTools cluster)
]
in case master of
<*> genMaybe genName -- gluster_file_storage_dir
<*> arbitrary -- instance_communication_network
<*> arbitrary -- zeroing_image
+ <*> arbitrary -- compression_tools
"OP_CLUSTER_REDIST_CONF" -> pure OpCodes.OpClusterRedistConf
"OP_CLUSTER_ACTIVATE_MASTER_IP" ->
pure OpCodes.OpClusterActivateMasterIp
"candidate_certs": {},
"instance_communication_network": "",
"zeroing_image": "",
+ "compression_tools": constants.IEC_DEFAULT_TOOLS,
},
"instances": {},
"disks": {},
cluster.get("instance_communication_network", "")
cluster["zeroing_image"] = \
cluster.get("zeroing_image", "")
+ cluster["compression_tools"] = \
+ cluster.get("compression_tools", constants.IEC_DEFAULT_TOOLS)
def UpgradeGroups(config_data):
if "zeroing_image" in cluster:
del cluster["zeroing_image"]
+ if "compression_tools" in cluster:
+ del cluster["compression_tools"]
+
def DowngradeGroups(config_data):
for group in config_data["nodegroups"].values():