Beispiel #1
0
    def _fdt(self, dict, allowed_values=None):
        if allowed_values is None:
            utils.ForceDictType(dict, self.KEY_TYPES)
        else:
            utils.ForceDictType(dict,
                                self.KEY_TYPES,
                                allowed_values=allowed_values)

        return dict
Beispiel #2
0
    def CheckPrereq(self):
        """Check prerequisites.

    This checks that the given group name is not an existing node group
    already.

    """
        try:
            existing_uuid = self.cfg.LookupNodeGroup(self.op.group_name)
        except errors.OpPrereqError:
            pass
        else:
            raise errors.OpPrereqError(
                "Desired group name '%s' already exists as a"
                " node group (UUID: %s)" % (self.op.group_name, existing_uuid),
                errors.ECODE_EXISTS)

        if self.op.ndparams:
            utils.ForceDictType(self.op.ndparams,
                                constants.NDS_PARAMETER_TYPES)

        if self.op.hv_state:
            self.new_hv_state = MergeAndVerifyHvState(self.op.hv_state, None)
        else:
            self.new_hv_state = None

        if self.op.disk_state:
            self.new_disk_state = MergeAndVerifyDiskState(
                self.op.disk_state, None)
        else:
            self.new_disk_state = None

        if self.op.diskparams:
            for templ in constants.DISK_TEMPLATES:
                if templ in self.op.diskparams:
                    utils.ForceDictType(self.op.diskparams[templ],
                                        constants.DISK_DT_TYPES)
            self.new_diskparams = self.op.diskparams
            try:
                utils.VerifyDictOptions(self.new_diskparams,
                                        constants.DISK_DT_DEFAULTS)
            except errors.OpPrereqError as err:
                raise errors.OpPrereqError(
                    "While verify diskparams options: %s" % err,
                    errors.ECODE_INVAL)
        else:
            self.new_diskparams = {}

        self._CheckIpolicy()
Beispiel #3
0
 def CheckArguments(self):
     # extra beparams
     if self.op.beparams:
         # fill the beparams dict
         objects.UpgradeBeParams(self.op.beparams)
         utils.ForceDictType(self.op.beparams,
                             constants.BES_PARAMETER_TYPES)
Beispiel #4
0
    def _UpdateAndVerifyDiskParams(old, new):
        """Updates and verifies disk parameters.

    """
        new_params = GetUpdatedParams(old, new)
        utils.ForceDictType(new_params, constants.DISK_DT_TYPES)
        return new_params
Beispiel #5
0
def GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
    """Return the new version of an instance policy.

  @param group_policy: whether this policy applies to a group and thus
    we should support removal of policy entries

  """
    ipolicy = copy.deepcopy(old_ipolicy)
    for key, value in new_ipolicy.items():
        if key not in constants.IPOLICY_ALL_KEYS:
            raise errors.OpPrereqError("Invalid key in new ipolicy: %s" % key,
                                       errors.ECODE_INVAL)
        if (not value or value == [constants.VALUE_DEFAULT]
                or value == constants.VALUE_DEFAULT):
            if group_policy:
                if key in ipolicy:
                    del ipolicy[key]
            else:
                raise errors.OpPrereqError(
                    "Can't unset ipolicy attribute '%s'"
                    " on the cluster'" % key, errors.ECODE_INVAL)
        else:
            if key in constants.IPOLICY_PARAMETERS:
                # FIXME: we assume all such values are float
                try:
                    ipolicy[key] = float(value)
                except (TypeError, ValueError), err:
                    raise errors.OpPrereqError(
                        "Invalid value for attribute"
                        " '%s': '%s', error: %s" % (key, value, err),
                        errors.ECODE_INVAL)
            elif key == constants.ISPECS_MINMAX:
                for minmax in value:
                    for k in minmax.keys():
                        utils.ForceDictType(minmax[k],
                                            constants.ISPECS_PARAMETER_TYPES)
                ipolicy[key] = value
            elif key == constants.ISPECS_STD:
                if group_policy:
                    msg = "%s cannot appear in group instance specs" % key
                    raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
                ipolicy[key] = GetUpdatedParams(old_ipolicy.get(key, {}),
                                                value,
                                                use_none=False,
                                                use_default=False)
                utils.ForceDictType(ipolicy[key],
                                    constants.ISPECS_PARAMETER_TYPES)
Beispiel #6
0
    def CheckPrereq(self):
        """Check prerequisites.

    """
        owned_instance_names = frozenset(
            self.owned_locks(locking.LEVEL_INSTANCE))

        # Check if locked instances are still correct
        CheckNodeGroupInstances(self.cfg, self.group_uuid,
                                owned_instance_names)

        self.group = self.cfg.GetNodeGroup(self.group_uuid)
        cluster = self.cfg.GetClusterInfo()

        if self.group is None:
            raise errors.OpExecError(
                "Could not retrieve group '%s' (UUID: %s)" %
                (self.op.group_name, self.group_uuid))

        if self.op.ndparams:
            new_ndparams = GetUpdatedParams(self.group.ndparams,
                                            self.op.ndparams)
            utils.ForceDictType(new_ndparams, constants.NDS_PARAMETER_TYPES)
            self.new_ndparams = new_ndparams

        if self.op.diskparams:
            diskparams = self.group.diskparams
            uavdp = self._UpdateAndVerifyDiskParams
            # For each disktemplate subdict update and verify the values
            new_diskparams = dict(
                (dt, uavdp(diskparams.get(dt, {}), self.op.diskparams[dt]))
                for dt in constants.DISK_TEMPLATES if dt in self.op.diskparams)
            # As we've all subdicts of diskparams ready, lets merge the actual
            # dict with all updated subdicts
            self.new_diskparams = objects.FillDict(diskparams, new_diskparams)

            try:
                utils.VerifyDictOptions(self.new_diskparams,
                                        constants.DISK_DT_DEFAULTS)
                CheckDiskAccessModeConsistency(self.new_diskparams,
                                               self.cfg,
                                               group=self.group)
            except errors.OpPrereqError as err:
                raise errors.OpPrereqError(
                    "While verify diskparams options: %s" % err,
                    errors.ECODE_INVAL)

        if self.op.hv_state:
            self.new_hv_state = MergeAndVerifyHvState(
                self.op.hv_state, self.group.hv_state_static)

        if self.op.disk_state:
            self.new_disk_state = \
              MergeAndVerifyDiskState(self.op.disk_state,
                                      self.group.disk_state_static)

        self._CheckIpolicy(cluster, owned_instance_names)
Beispiel #7
0
def ComputeFullBeParams(op, cluster):
    """Computes the full beparams.

  @param op: The instance opcode
  @param cluster: The cluster config object

  @return: The fully filled beparams

  """
    default_beparams = cluster.beparams[constants.PP_DEFAULT]
    for param, value in op.beparams.iteritems():
        if value == constants.VALUE_AUTO:
            op.beparams[param] = default_beparams[param]
    objects.UpgradeBeParams(op.beparams)
    utils.ForceDictType(op.beparams, constants.BES_PARAMETER_TYPES)
    return cluster.SimpleFillBE(op.beparams)
def VerifyType(owner, attr, value, template, callback):
  """Checks if an attribute has correct form.

  @type owner: str
  @param owner: name of the object containing the attribute
  @type attr: str
  @param attr: name of the attribute
  @type value: dict
  @param value: actual value of the attribute
  @type template: dict
  @param template: expected types of the keys
  @type callback: callable
  @param callback: will be called if there is an error

  """
  try:
    utils.ForceDictType(value, template)
  except errors.GenericError, err:
    return callback("%s has invalid %s: %s" % (owner, attr, err))
Beispiel #9
0
    def CheckPrereq(self):
        """Check prerequisites.

    This checks that the instance is in the cluster.

    """
        self.instance = self.cfg.GetInstanceInfo(self.op.instance_uuid)
        assert self.instance is not None, \
          "Cannot retrieve locked instance %s" % self.op.instance_name

        cluster = self.cfg.GetClusterInfo()
        # extra hvparams
        if self.op.hvparams:
            # check hypervisor parameter syntax (locally)
            utils.ForceDictType(self.op.hvparams,
                                constants.HVS_PARAMETER_TYPES)
            filled_hvp = cluster.FillHV(self.instance)
            filled_hvp.update(self.op.hvparams)
            hv_type = hypervisor.GetHypervisorClass(self.instance.hypervisor)
            hv_type.CheckParameterSyntax(filled_hvp)
            CheckHVParams(self, self.cfg.GetInstanceNodes(self.instance.uuid),
                          self.instance.hypervisor, filled_hvp)

        CheckInstanceState(self, self.instance, INSTANCE_ONLINE)

        self.primary_offline = \
          self.cfg.GetNodeInfo(self.instance.primary_node).offline

        if self.primary_offline and self.op.ignore_offline_nodes:
            self.LogWarning("Ignoring offline primary node")

            if self.op.hvparams or self.op.beparams:
                self.LogWarning("Overridden parameters are ignored")
        else:
            CheckNodeOnline(self, self.instance.primary_node)

            bep = self.cfg.GetClusterInfo().FillBE(self.instance)
            bep.update(self.op.beparams)

            # check bridges existence
            CheckInstanceBridgesExist(self, self.instance)

            remote_info = self.rpc.call_instance_info(
                self.instance.primary_node, self.instance.name,
                self.instance.hypervisor,
                cluster.hvparams[self.instance.hypervisor])
            remote_info.Raise("Error checking node %s" %
                              self.cfg.GetNodeName(self.instance.primary_node),
                              prereq=True,
                              ecode=errors.ECODE_ENVIRON)

            self.requires_cleanup = False

            if remote_info.payload:
                if _IsInstanceUserDown(self.cfg.GetClusterInfo(),
                                       self.instance, remote_info.payload):
                    self.requires_cleanup = True
            else:  # not running already
                CheckNodeFreeMemory(
                    self, self.instance.primary_node,
                    "starting instance %s" % self.instance.name,
                    bep[constants.BE_MINMEM], self.instance.hypervisor,
                    self.cfg.GetClusterInfo().hvparams[
                        self.instance.hypervisor])
def InitCluster(
        cluster_name,
        mac_prefix,  # pylint: disable=R0913, R0914
        master_netmask,
        master_netdev,
        file_storage_dir,
        shared_file_storage_dir,
        gluster_storage_dir,
        candidate_pool_size,
        secondary_ip=None,
        vg_name=None,
        beparams=None,
        nicparams=None,
        ndparams=None,
        hvparams=None,
        diskparams=None,
        enabled_hypervisors=None,
        modify_etc_hosts=True,
        modify_ssh_setup=True,
        maintain_node_health=False,
        drbd_helper=None,
        uid_pool=None,
        default_iallocator=None,
        default_iallocator_params=None,
        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,
        install_image=None,
        zeroing_image=None,
        compression_tools=None,
        enabled_user_shutdown=False):
    """Initialise the cluster.

  @type candidate_pool_size: int
  @param candidate_pool_size: master candidate pool size

  @type enabled_disk_templates: list of string
  @param enabled_disk_templates: list of disk_templates to be used in this
    cluster

  @type enabled_user_shutdown: bool
  @param enabled_user_shutdown: whether user shutdown is enabled cluster
                                wide

  """
    # TODO: complete the docstring
    if config.ConfigWriter.IsCluster():
        raise errors.OpPrereqError("Cluster is already initialised",
                                   errors.ECODE_STATE)

    data_dir = vcluster.AddNodePrefix(pathutils.DATA_DIR)
    queue_dir = vcluster.AddNodePrefix(pathutils.QUEUE_DIR)
    archive_dir = vcluster.AddNodePrefix(pathutils.JOB_QUEUE_ARCHIVE_DIR)
    for ddir in [queue_dir, data_dir, archive_dir]:
        if os.path.isdir(ddir):
            for entry in os.listdir(ddir):
                if not os.path.isdir(os.path.join(ddir, entry)):
                    raise errors.OpPrereqError(
                        "%s contains non-directory entries like %s. Remove left-overs of an"
                        " old cluster before initialising a new one" %
                        (ddir, entry), errors.ECODE_STATE)

    if not enabled_hypervisors:
        raise errors.OpPrereqError(
            "Enabled hypervisors list must contain at"
            " least one member", errors.ECODE_INVAL)
    invalid_hvs = set(enabled_hypervisors) - constants.HYPER_TYPES
    if invalid_hvs:
        raise errors.OpPrereqError(
            "Enabled hypervisors contains invalid"
            " entries: %s" % invalid_hvs, errors.ECODE_INVAL)

    _InitCheckEnabledDiskTemplates(enabled_disk_templates)

    try:
        ipcls = netutils.IPAddress.GetClassFromIpVersion(primary_ip_version)
    except errors.ProgrammerError:
        raise errors.OpPrereqError(
            "Invalid primary ip version: %d." % primary_ip_version,
            errors.ECODE_INVAL)

    hostname = netutils.GetHostname(family=ipcls.family)
    if not ipcls.IsValid(hostname.ip):
        raise errors.OpPrereqError(
            "This host's IP (%s) is not a valid IPv%d"
            " address." % (hostname.ip, primary_ip_version),
            errors.ECODE_INVAL)

    if ipcls.IsLoopback(hostname.ip):
        raise errors.OpPrereqError(
            "This host's IP (%s) resolves to a loopback"
            " address. Please fix DNS or %s." %
            (hostname.ip, pathutils.ETC_HOSTS), errors.ECODE_ENVIRON)

    if not ipcls.Own(hostname.ip):
        raise errors.OpPrereqError(
            "Inconsistency: this host's name resolves"
            " to %s,\nbut this ip address does not"
            " belong to this host" % hostname.ip, errors.ECODE_ENVIRON)

    clustername = netutils.GetHostname(name=cluster_name, family=ipcls.family)

    if netutils.TcpPing(clustername.ip,
                        constants.DEFAULT_NODED_PORT,
                        timeout=5):
        raise errors.OpPrereqError("Cluster IP already active",
                                   errors.ECODE_NOTUNIQUE)

    if not secondary_ip:
        if primary_ip_version == constants.IP6_VERSION:
            raise errors.OpPrereqError(
                "When using a IPv6 primary address, a valid"
                " IPv4 address must be given as secondary", errors.ECODE_INVAL)
        secondary_ip = hostname.ip

    if not netutils.IP4Address.IsValid(secondary_ip):
        raise errors.OpPrereqError(
            "Secondary IP address (%s) has to be a valid"
            " IPv4 address." % secondary_ip, errors.ECODE_INVAL)

    if not netutils.IP4Address.Own(secondary_ip):
        raise errors.OpPrereqError(
            "You gave %s as secondary IP,"
            " but it does not belong to this host." % secondary_ip,
            errors.ECODE_ENVIRON)

    if master_netmask is not None:
        if not ipcls.ValidateNetmask(master_netmask):
            raise errors.OpPrereqError(
                "CIDR netmask (%s) not valid for IPv%s " %
                (master_netmask, primary_ip_version), errors.ECODE_INVAL)
    else:
        master_netmask = ipcls.iplen

    if vg_name:
        # Check if volume group is valid
        vgstatus = utils.CheckVolumeGroupSize(utils.ListVolumeGroups(),
                                              vg_name, constants.MIN_VG_SIZE)
        if vgstatus:
            raise errors.OpPrereqError("Error: %s" % vgstatus,
                                       errors.ECODE_INVAL)

    drbd_enabled = constants.DT_DRBD8 in enabled_disk_templates
    _InitCheckDrbdHelper(drbd_helper, drbd_enabled)

    logging.debug("Stopping daemons (if any are running)")
    result = utils.RunCmd([pathutils.DAEMON_UTIL, "stop-all"])
    if result.failed:
        raise errors.OpExecError("Could not stop daemons, command %s"
                                 " had exitcode %s and error '%s'" %
                                 (result.cmd, result.exit_code, result.output))

    file_storage_dir = _PrepareFileStorage(enabled_disk_templates,
                                           file_storage_dir)
    shared_file_storage_dir = _PrepareSharedFileStorage(
        enabled_disk_templates, shared_file_storage_dir)
    gluster_storage_dir = _PrepareGlusterStorage(enabled_disk_templates,
                                                 gluster_storage_dir)

    if not re.match("^[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}$", mac_prefix):
        raise errors.OpPrereqError(
            "Invalid mac prefix given '%s'" % mac_prefix, errors.ECODE_INVAL)

    if not nicparams.get('mode', None) == constants.NIC_MODE_OVS:
        # Do not do this check if mode=openvswitch, since the openvswitch is not
        # created yet
        result = utils.RunCmd(["ip", "link", "show", "dev", master_netdev])
        if result.failed:
            raise errors.OpPrereqError(
                "Invalid master netdev given (%s): '%s'" %
                (master_netdev, result.output.strip()), errors.ECODE_INVAL)

    dirs = [(pathutils.RUN_DIR, constants.RUN_DIRS_MODE)]
    utils.EnsureDirs(dirs)

    objects.UpgradeBeParams(beparams)
    utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
    utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)

    objects.NIC.CheckParameterSyntax(nicparams)

    full_ipolicy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy)
    _RestrictIpolicyToEnabledDiskTemplates(full_ipolicy,
                                           enabled_disk_templates)

    if ndparams is not None:
        utils.ForceDictType(ndparams, constants.NDS_PARAMETER_TYPES)
    else:
        ndparams = dict(constants.NDC_DEFAULTS)

    # This is ugly, as we modify the dict itself
    # FIXME: Make utils.ForceDictType pure functional or write a wrapper
    # around it
    if hv_state:
        for hvname, hvs_data in hv_state.items():
            utils.ForceDictType(hvs_data, constants.HVSTS_PARAMETER_TYPES)
            hv_state[hvname] = objects.Cluster.SimpleFillHvState(hvs_data)
    else:
        hv_state = dict((hvname, constants.HVST_DEFAULTS)
                        for hvname in enabled_hypervisors)

    # FIXME: disk_state has no default values yet
    if disk_state:
        for storage, ds_data in disk_state.items():
            if storage not in constants.DS_VALID_TYPES:
                raise errors.OpPrereqError(
                    "Invalid storage type in disk state: %s" % storage,
                    errors.ECODE_INVAL)
            for ds_name, state in ds_data.items():
                utils.ForceDictType(state, constants.DSS_PARAMETER_TYPES)
                ds_data[ds_name] = objects.Cluster.SimpleFillDiskState(state)

    # hvparams is a mapping of hypervisor->hvparams dict
    for hv_name, hv_params in hvparams.iteritems():
        utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES)
        hv_class = hypervisor.GetHypervisor(hv_name)
        hv_class.CheckParameterSyntax(hv_params)

    # diskparams is a mapping of disk-template->diskparams dict
    for template, dt_params in diskparams.items():
        param_keys = set(dt_params.keys())
        default_param_keys = set(constants.DISK_DT_DEFAULTS[template].keys())
        if not (param_keys <= default_param_keys):
            unknown_params = param_keys - default_param_keys
            raise errors.OpPrereqError(
                "Invalid parameters for disk template %s:"
                " %s" % (template, utils.CommaJoin(unknown_params)),
                errors.ECODE_INVAL)
        utils.ForceDictType(dt_params, constants.DISK_DT_TYPES)
        if template == constants.DT_DRBD8 and vg_name is not None:
            # The default METAVG value is equal to the VG name set at init time,
            # if provided
            dt_params[constants.DRBD_DEFAULT_METAVG] = vg_name

    try:
        utils.VerifyDictOptions(diskparams, constants.DISK_DT_DEFAULTS)
    except errors.OpPrereqError, err:
        raise errors.OpPrereqError("While verify diskparam options: %s" % err,
                                   errors.ECODE_INVAL)
Beispiel #11
0
def InitCluster(
        cluster_name,
        mac_prefix,  # pylint: disable=R0913, R0914
        master_netmask,
        master_netdev,
        file_storage_dir,
        shared_file_storage_dir,
        gluster_storage_dir,
        candidate_pool_size,
        ssh_key_type,
        ssh_key_bits,
        secondary_ip=None,
        vg_name=None,
        beparams=None,
        nicparams=None,
        ndparams=None,
        hvparams=None,
        diskparams=None,
        enabled_hypervisors=None,
        modify_etc_hosts=True,
        modify_ssh_setup=True,
        maintain_node_health=False,
        drbd_helper=None,
        uid_pool=None,
        default_iallocator=None,
        default_iallocator_params=None,
        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,
        install_image=None,
        zeroing_image=None,
        compression_tools=None,
        enabled_user_shutdown=False):
    """Initialise the cluster.

  @type candidate_pool_size: int
  @param candidate_pool_size: master candidate pool size

  @type enabled_disk_templates: list of string
  @param enabled_disk_templates: list of disk_templates to be used in this
    cluster

  @type enabled_user_shutdown: bool
  @param enabled_user_shutdown: whether user shutdown is enabled cluster
                                wide

  """
    # TODO: complete the docstring
    if config.ConfigWriter.IsCluster():
        raise errors.OpPrereqError("Cluster is already initialised",
                                   errors.ECODE_STATE)

    data_dir = vcluster.AddNodePrefix(pathutils.DATA_DIR)
    queue_dir = vcluster.AddNodePrefix(pathutils.QUEUE_DIR)
    archive_dir = vcluster.AddNodePrefix(pathutils.JOB_QUEUE_ARCHIVE_DIR)
    for ddir in [queue_dir, data_dir, archive_dir]:
        if os.path.isdir(ddir):
            for entry in os.listdir(ddir):
                if not os.path.isdir(os.path.join(ddir, entry)):
                    raise errors.OpPrereqError(
                        "%s contains non-directory entries like %s. Remove left-overs of an"
                        " old cluster before initialising a new one" %
                        (ddir, entry), errors.ECODE_STATE)

    if not enabled_hypervisors:
        raise errors.OpPrereqError(
            "Enabled hypervisors list must contain at"
            " least one member", errors.ECODE_INVAL)
    invalid_hvs = set(enabled_hypervisors) - constants.HYPER_TYPES
    if invalid_hvs:
        raise errors.OpPrereqError(
            "Enabled hypervisors contains invalid"
            " entries: %s" % invalid_hvs, errors.ECODE_INVAL)

    _InitCheckEnabledDiskTemplates(enabled_disk_templates)

    try:
        ipcls = netutils.IPAddress.GetClassFromIpVersion(primary_ip_version)
    except errors.ProgrammerError:
        raise errors.OpPrereqError(
            "Invalid primary ip version: %d." % primary_ip_version,
            errors.ECODE_INVAL)

    hostname = netutils.GetHostname(family=ipcls.family)
    if not ipcls.IsValid(hostname.ip):
        raise errors.OpPrereqError(
            "This host's IP (%s) is not a valid IPv%d"
            " address." % (hostname.ip, primary_ip_version),
            errors.ECODE_INVAL)

    if ipcls.IsLoopback(hostname.ip):
        raise errors.OpPrereqError(
            "This host's IP (%s) resolves to a loopback"
            " address. Please fix DNS or %s." %
            (hostname.ip, pathutils.ETC_HOSTS), errors.ECODE_ENVIRON)

    if not ipcls.Own(hostname.ip):
        raise errors.OpPrereqError(
            "Inconsistency: this host's name resolves"
            " to %s,\nbut this ip address does not"
            " belong to this host" % hostname.ip, errors.ECODE_ENVIRON)

    clustername = netutils.GetHostname(name=cluster_name, family=ipcls.family)

    if netutils.TcpPing(clustername.ip,
                        constants.DEFAULT_NODED_PORT,
                        timeout=5):
        raise errors.OpPrereqError("Cluster IP already active",
                                   errors.ECODE_NOTUNIQUE)

    if not secondary_ip:
        if primary_ip_version == constants.IP6_VERSION:
            raise errors.OpPrereqError(
                "When using a IPv6 primary address, a valid"
                " IPv4 address must be given as secondary", errors.ECODE_INVAL)
        secondary_ip = hostname.ip

    if not netutils.IP4Address.IsValid(secondary_ip):
        raise errors.OpPrereqError(
            "Secondary IP address (%s) has to be a valid"
            " IPv4 address." % secondary_ip, errors.ECODE_INVAL)

    if not netutils.IP4Address.Own(secondary_ip):
        raise errors.OpPrereqError(
            "You gave %s as secondary IP,"
            " but it does not belong to this host." % secondary_ip,
            errors.ECODE_ENVIRON)

    if master_netmask is not None:
        if not ipcls.ValidateNetmask(master_netmask):
            raise errors.OpPrereqError(
                "CIDR netmask (%s) not valid for IPv%s " %
                (master_netmask, primary_ip_version), errors.ECODE_INVAL)
    else:
        master_netmask = ipcls.iplen

    if vg_name:
        # Check if volume group is valid
        vgstatus = utils.CheckVolumeGroupSize(utils.ListVolumeGroups(),
                                              vg_name, constants.MIN_VG_SIZE)
        if vgstatus:
            raise errors.OpPrereqError("Error: %s" % vgstatus,
                                       errors.ECODE_INVAL)

    drbd_enabled = constants.DT_DRBD8 in enabled_disk_templates
    _InitCheckDrbdHelper(drbd_helper, drbd_enabled)

    logging.debug("Stopping daemons (if any are running)")
    result = utils.RunCmd([pathutils.DAEMON_UTIL, "stop-all"])
    if result.failed:
        raise errors.OpExecError("Could not stop daemons, command %s"
                                 " had exitcode %s and error '%s'" %
                                 (result.cmd, result.exit_code, result.output))

    file_storage_dir = _PrepareFileStorage(enabled_disk_templates,
                                           file_storage_dir)
    shared_file_storage_dir = _PrepareSharedFileStorage(
        enabled_disk_templates, shared_file_storage_dir)
    gluster_storage_dir = _PrepareGlusterStorage(enabled_disk_templates,
                                                 gluster_storage_dir)

    if not re.match("^[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}$", mac_prefix):
        raise errors.OpPrereqError(
            "Invalid mac prefix given '%s'" % mac_prefix, errors.ECODE_INVAL)

    if not nicparams.get('mode', None) == constants.NIC_MODE_OVS:
        # Do not do this check if mode=openvswitch, since the openvswitch is not
        # created yet
        result = utils.RunCmd(["ip", "link", "show", "dev", master_netdev])
        if result.failed:
            raise errors.OpPrereqError(
                "Invalid master netdev given (%s): '%s'" %
                (master_netdev, result.output.strip()), errors.ECODE_INVAL)

    dirs = [(pathutils.RUN_DIR, constants.RUN_DIRS_MODE)]
    utils.EnsureDirs(dirs)

    objects.UpgradeBeParams(beparams)
    utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
    utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)

    objects.NIC.CheckParameterSyntax(nicparams)

    full_ipolicy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy)
    _RestrictIpolicyToEnabledDiskTemplates(full_ipolicy,
                                           enabled_disk_templates)

    if ndparams is not None:
        utils.ForceDictType(ndparams, constants.NDS_PARAMETER_TYPES)
    else:
        ndparams = dict(constants.NDC_DEFAULTS)

    # This is ugly, as we modify the dict itself
    # FIXME: Make utils.ForceDictType pure functional or write a wrapper
    # around it
    if hv_state:
        for hvname, hvs_data in hv_state.items():
            utils.ForceDictType(hvs_data, constants.HVSTS_PARAMETER_TYPES)
            hv_state[hvname] = objects.Cluster.SimpleFillHvState(hvs_data)
    else:
        hv_state = dict((hvname, constants.HVST_DEFAULTS)
                        for hvname in enabled_hypervisors)

    # FIXME: disk_state has no default values yet
    if disk_state:
        for storage, ds_data in disk_state.items():
            if storage not in constants.DS_VALID_TYPES:
                raise errors.OpPrereqError(
                    "Invalid storage type in disk state: %s" % storage,
                    errors.ECODE_INVAL)
            for ds_name, state in ds_data.items():
                utils.ForceDictType(state, constants.DSS_PARAMETER_TYPES)
                ds_data[ds_name] = objects.Cluster.SimpleFillDiskState(state)

    # hvparams is a mapping of hypervisor->hvparams dict
    for hv_name, hv_params in hvparams.items():
        utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES)
        hv_class = hypervisor.GetHypervisor(hv_name)
        hv_class.CheckParameterSyntax(hv_params)

    # diskparams is a mapping of disk-template->diskparams dict
    for template, dt_params in diskparams.items():
        param_keys = set(dt_params.keys())
        default_param_keys = set(constants.DISK_DT_DEFAULTS[template].keys())
        if param_keys > default_param_keys:
            unknown_params = param_keys - default_param_keys
            raise errors.OpPrereqError(
                "Invalid parameters for disk template %s:"
                " %s" % (template, utils.CommaJoin(unknown_params)),
                errors.ECODE_INVAL)
        utils.ForceDictType(dt_params, constants.DISK_DT_TYPES)
        if template == constants.DT_DRBD8 and vg_name is not None:
            # The default METAVG value is equal to the VG name set at init time,
            # if provided
            dt_params[constants.DRBD_DEFAULT_METAVG] = vg_name

    try:
        utils.VerifyDictOptions(diskparams, constants.DISK_DT_DEFAULTS)
    except errors.OpPrereqError as err:
        raise errors.OpPrereqError("While verify diskparam options: %s" % err,
                                   errors.ECODE_INVAL)

    # set up ssh config and /etc/hosts
    rsa_sshkey = ""
    dsa_sshkey = ""
    if os.path.isfile(pathutils.SSH_HOST_RSA_PUB):
        sshline = utils.ReadFile(pathutils.SSH_HOST_RSA_PUB)
        rsa_sshkey = sshline.split(" ")[1]
    if os.path.isfile(pathutils.SSH_HOST_DSA_PUB):
        sshline = utils.ReadFile(pathutils.SSH_HOST_DSA_PUB)
        dsa_sshkey = sshline.split(" ")[1]
    if not rsa_sshkey and not dsa_sshkey:
        raise errors.OpPrereqError("Failed to find SSH public keys",
                                   errors.ECODE_ENVIRON)

    if modify_etc_hosts:
        utils.AddHostToEtcHosts(hostname.name, hostname.ip)

    if modify_ssh_setup:
        ssh.InitSSHSetup(ssh_key_type, ssh_key_bits)

    if default_iallocator is not None:
        alloc_script = utils.FindFile(default_iallocator,
                                      constants.IALLOCATOR_SEARCH_PATH,
                                      os.path.isfile)
        if alloc_script is None:
            raise errors.OpPrereqError(
                "Invalid default iallocator script '%s'"
                " specified" % default_iallocator, errors.ECODE_INVAL)
    else:
        # default to htools
        if utils.FindFile(constants.IALLOC_HAIL,
                          constants.IALLOCATOR_SEARCH_PATH, os.path.isfile):
            default_iallocator = constants.IALLOC_HAIL

    # check if we have all the users we need
    try:
        runtime.GetEnts()
    except errors.ConfigurationError as err:
        raise errors.OpPrereqError(
            "Required system user/group missing: %s" % err,
            errors.ECODE_ENVIRON)

    candidate_certs = {}

    now = time.time()

    if compression_tools is not None:
        cluster.CheckCompressionTools(compression_tools)

    initial_dc_config = dict(active=True,
                             interval=int(constants.MOND_TIME_INTERVAL * 1e6))
    data_collectors = dict((name, initial_dc_config.copy())
                           for name in constants.DATA_COLLECTOR_NAMES)

    # init of cluster config file
    cluster_config = objects.Cluster(
        serial_no=1,
        rsahostkeypub=rsa_sshkey,
        dsahostkeypub=dsa_sshkey,
        highest_used_port=(constants.FIRST_DRBD_PORT - 1),
        mac_prefix=mac_prefix,
        volume_group_name=vg_name,
        tcpudp_port_pool=set(),
        master_ip=clustername.ip,
        master_netmask=master_netmask,
        master_netdev=master_netdev,
        cluster_name=clustername.name,
        file_storage_dir=file_storage_dir,
        shared_file_storage_dir=shared_file_storage_dir,
        gluster_storage_dir=gluster_storage_dir,
        enabled_hypervisors=enabled_hypervisors,
        beparams={constants.PP_DEFAULT: beparams},
        nicparams={constants.PP_DEFAULT: nicparams},
        ndparams=ndparams,
        hvparams=hvparams,
        diskparams=diskparams,
        candidate_pool_size=candidate_pool_size,
        modify_etc_hosts=modify_etc_hosts,
        modify_ssh_setup=modify_ssh_setup,
        uid_pool=uid_pool,
        ctime=now,
        mtime=now,
        maintain_node_health=maintain_node_health,
        data_collectors=data_collectors,
        drbd_usermode_helper=drbd_helper,
        default_iallocator=default_iallocator,
        default_iallocator_params=default_iallocator_params,
        primary_ip_family=ipcls.family,
        prealloc_wipe_disks=prealloc_wipe_disks,
        use_external_mip_script=use_external_mip_script,
        ipolicy=full_ipolicy,
        hv_state_static=hv_state,
        disk_state_static=disk_state,
        enabled_disk_templates=enabled_disk_templates,
        candidate_certs=candidate_certs,
        osparams={},
        osparams_private_cluster={},
        install_image=install_image,
        zeroing_image=zeroing_image,
        compression_tools=compression_tools,
        enabled_user_shutdown=enabled_user_shutdown,
        ssh_key_type=ssh_key_type,
        ssh_key_bits=ssh_key_bits,
    )
    master_node_config = objects.Node(
        name=hostname.name,
        primary_ip=hostname.ip,
        secondary_ip=secondary_ip,
        serial_no=1,
        master_candidate=True,
        offline=False,
        drained=False,
        ctime=now,
        mtime=now,
    )
    InitConfig(constants.CONFIG_VERSION, cluster_config, master_node_config)
    cfg = config.ConfigWriter(offline=True)
    ssh.WriteKnownHostsFile(cfg, pathutils.SSH_KNOWN_HOSTS_FILE)
    cfg.Update(cfg.GetClusterInfo(), logging.error)
    ssconf.WriteSsconfFiles(cfg.GetSsconfValues())

    master_uuid = cfg.GetMasterNode()
    if modify_ssh_setup:
        ssh.InitPubKeyFile(master_uuid, ssh_key_type)
    # set up the inter-node password and certificate
    _InitGanetiServerSetup(hostname.name, cfg)

    logging.debug("Starting daemons")
    result = utils.RunCmd([pathutils.DAEMON_UTIL, "start-all"])
    if result.failed:
        raise errors.OpExecError("Could not start daemons, command %s"
                                 " had exitcode %s and error %s" %
                                 (result.cmd, result.exit_code, result.output))

    _WaitForMasterDaemon()
Beispiel #12
0
 def fn(old, value):
     new = GetUpdatedParams(old, value)
     utils.ForceDictType(new, type_check)
     return new