def restart(self, **kwargs): service_name = self._get_sysvinit_name(**kwargs) arguments = [ 'service', service_name, 'restart' ] utils.execute_local_command(arguments)
def on_boot_disable(self, **kwargs): service_name = self._get_sysvinit_name(**kwargs) arguments = [ 'chkconfig', service_name, 'off' ] utils.execute_local_command(arguments)
def on_boot_disable(self, **kwargs): systemctl_name = self._get_systemctl_name(**kwargs) arguments = [ util_which.which_systemctl.path, 'disable', systemctl_name ] utils.execute_local_command(arguments)
def is_running(self, **kwargs): service_name = self._get_sysvinit_name(**kwargs) arguments = [ 'chkconfig', service_name, 'status' ] utils.execute_local_command(arguments)
def _update_partition(action, dev, description): # try to make sure the kernel refreshes the table. note # that if this gets ebusy, we are probably racing with # udev because it already updated it.. ignore failure here. # On RHEL and CentOS distros, calling partprobe forces a reboot of the # server. Since we are not resizing partitons so we rely on calling # partx utils.execute_local_command([ constants._path_partprobe, dev, ], )
def zap(dev = None, **kwargs): """ Destroy the partition table and content of a given disk. """ if dev is not None: log.warning("Depricated use of function, use kwargs") dev = kwargs.get("dev", dev) if dev == None: raise Error('Cannot find', dev) if not os.path.exists(dev): raise Error('Cannot find', dev) dmode = os.stat(dev).st_mode mdl = model.model(**kwargs) osdc = osd.osd_ctrl(mdl) if not stat.S_ISBLK(dmode) or osdc.is_partition(dev): raise Error('not full block device; cannot zap', dev) try: log.debug('Zapping partition table on %s', dev) # try to wipe out any GPT partition table backups. sgdisk # isn't too thorough. lba_size = 4096 size = 33 * lba_size with file(dev, 'wb') as dev_file: dev_file.seek(-size, os.SEEK_END) dev_file.write(size*'\0') utils.execute_local_command( [ util_which.which_sgdisk.path, '--zap-all', '--', dev, ], ) utils.execute_local_command( [ util_which.which_sgdisk.path, '--clear', '--mbrtogpt', '--', dev, ], ) _update_partition('-d', dev, 'zapped') except subprocess.CalledProcessError as e: raise Error(e) return True
def retrive_osd_details(device_name): osd_details = {} if device_name is None: return None try: tmpd = tempfile.mkdtemp() try: out_mnt = utils.execute_local_command(['mount',device_name,tmpd]) if out_mnt['retcode'] == 0: osd_details = _retrive_osd_details_from_dir(tmpd) finally: utils.execute_local_command(['umount',tmpd]) finally: os.rmdir(tmpd) return osd_details
def _update_partition(action, dev, description): # try to make sure the kernel refreshes the table. note # that if this gets ebusy, we are probably racing with # udev because it already updated it.. ignore failure here. # On RHEL and CentOS distros, calling partprobe forces a reboot of the # server. Since we are not resizing partitons so we rely on calling # partx utils.execute_local_command( [ constants._path_partprobe, dev, ], )
def is_running(self, **kwargs): systemctl_name = self._get_systemctl_name(**kwargs) arguments = [ util_which.which_systemctl.path, 'show', '--property', 'ActiveState', systemctl_name, ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise init_exception_service("failed to query state from '%s' Error rc=%s, stdout=%s stderr=%s" % ( systemctl_name, output["retcode"], output["stdout"], output["stderr"]) ) running = None for item in output["stdout"].split('\n'): split_item = item.split('=') key = split_item[0] value = "=".join(split_item[1:]) if key == "ActiveState": if value == "active": running = True else: running = False if running == None: raise init_exception_service("failed to get ActiveState from '%s'" % ( systemctl_name)) return running
def is_running(self, **kwargs): systemctl_name = self._get_systemctl_name(**kwargs) arguments = [ constants._path_systemctl, 'show', '--property', 'ActiveState', systemctl_name, ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise init_exception_service( "failed to query state from '%s' Error rc=%s, stdout=%s stderr=%s" % (systemctl_name, output["retcode"], output["stdout"], output["stderr"])) running = None for item in output["stdout"].split('\n'): split_item = item.split('=') key = split_item[0] value = "=".join(split_item[1:]) if key == "ActiveState": if value == "active": running = True else: running = False if running == None: raise init_exception_service( "failed to get ActiveState from '%s'" % (systemctl_name)) return running
def unmount_osd(self): for part in self.model.partitions_osd: disk = self.model.part_pairent.get(part) if disk is None: continue disk_details = self.model.lsblk.get(disk) if disk_details is None: continue all_parts = disk_details.get('PARTITION') if all_parts is None: continue part_details = all_parts.get(part) if part_details is None: continue mountpoint = part_details.get("MOUNTPOINT") if mountpoint is None: continue arguments = [ "umount", mountpoint ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] ))
def prepare(self): path_bootstrap_keyring = keyring._get_path_keyring_mds( self.model.cluster_name) if not os.path.isfile(path_bootstrap_keyring): raise Error("Keyring not found at %s" % (path_bootstrap_keyring)) if not os.path.isdir(self.model.path_systemd_env): log.info("mkdir %s" % (self.model.path_systemd_env)) os.makedirs(self.model.path_systemd_env) if not os.path.isdir(self.mds_path_lib): log.info("mkdir %s" % (self.mds_path_lib)) os.makedirs(self.mds_path_lib) mds_path_keyring = os.path.join(self.mds_path_lib, 'keyring') if not os.path.isfile(mds_path_keyring): log.info("creating %s" % (mds_path_keyring)) arguments = [ 'ceph', '--connect-timeout', '5', '--cluster', self.model.cluster_name, '--name', 'client.bootstrap-mds', '--keyring', path_bootstrap_keyring, 'auth', 'get-or-create', 'mds.{name}'.format(name=self.mds_name), 'osd', 'allow rwx', 'mds', 'allow', 'mon', 'allow profile mds', '-o', mds_path_keyring ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: if os.path.isfile(mds_path_keyring): log.info("Cleaning up new key:%s" % (mds_path_keyring)) os.remove(mds_path_keyring) raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def auth_add(self, **kwargs): """ Authorise keyring """ self.model.kargs_apply(**kwargs) u = mdl_updater.model_updater(self.model) u.hostname_refresh() if self.model.cluster_name == None: u.defaults_refresh() keyring_path = self.get_path_keyring() if not os.path.isfile(keyring_path): raise Error("rgw keyring not found") u.load_confg(self.model.cluster_name) u.mon_members_refresh() q = mdl_query.mdl_query(self.model) if not q.mon_is(): raise Error("Not ruining a mon daemon") u.mon_status() if not q.mon_quorum(): raise Error("mon daemon is not in quorum") arguments = [ "ceph", "auth", "import", "-i", keyring_path ] cmd_out = utils.execute_local_command(arguments) return True
def auth_add(self, keyring_type): """ Authorise keyring """ keyringobj = keyring.keyring_facard(self.model) keyringobj.key_type = keyring_type if not keyringobj.present(): raise Error("rgw keyring not found") q = mdl_query.mdl_query(self.model) if q.mon_is() and q.mon_quorum() is False: raise Error("mon daemon is not in quorum") arguments = [ "ceph", "auth", "import", "-i", keyringobj.keyring_path_get() ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) return True
def _pool_adder(self, name, **kwargs): pg_num = kwargs.get("pg_num", 8) pgp_num = kwargs.get("pgp_num", pg_num) pool_type = kwargs.get("pool_type") er_profile = kwargs.get("erasure_code_profile") crush_ruleset_name = kwargs.get("crush_ruleset") arguments = [ 'ceph', 'osd', 'pool', 'create', name, str(pg_num) ] if pgp_num != None: arguments.append(str(pgp_num)) if pool_type == "replicated": arguments.append("replicated") if pool_type == "erasure": arguments.append("erasure") arguments.append("erasure-code-profile=%s" % (er_profile)) if crush_ruleset_name != None: arguments.append(crush_ruleset_name) output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def activate_partition(self, partition, **kwargs): dmcrypt = kwargs.get("dmcrypt") dmcrypt_key_dir = kwargs.get("dmcrypt_key_dir") arguments = [ 'ceph-disk', '-v', 'activate', '--mark-init', self.model.init, '--mount', ] if dmcrypt is not None: arguments.append("--dmcrypt") if dmcrypt_key_dir is not None: arguments.append("--dmcrypt-key-dir") arguments.append(dmcrypt_key_dir) arguments.append(partition) output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) return True
def ceph_version_refresh(self): arguments = ["ceph", "--version"] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) version_raw = output["stdout"].strip() version_raw_split = shlex.split(version_raw) if len(version_raw_split) != 4: raise Error("ceph returned an invalid version:'%s' " % (version_raw)) if version_raw_split[0] != "ceph": raise Error( "ceph returned an invalid version first value is not ceph:'%s' " % (version_raw)) if version_raw_split[1] != "version": raise Error( "ceph returned an invalid version second value is not 'version':'%s' " % (version_raw)) version_public_raw = version_raw_split[2] version_git_raw = version_raw_split[2] version_public = version_public_raw.split(".") if len(version_public) < 3: raise Error( "ceph returned an invalid version second value is not 'version':'%s' " % (version_raw)) self.model.ceph_version.major = int(version_public[0]) self.model.ceph_version.minor = int(version_public[1]) self.model.ceph_version.revision = ".".join(version_public[2:]) self.model.ceph_version.uuid = version_raw_split[3].strip("()")
def ceph_version_refresh(self): arguments = [ "ceph", "--version" ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) version_raw = output["stdout"].strip() version_raw_split = shlex.split(version_raw) if len(version_raw_split) != 4: raise Error("ceph returned an invalid version:'%s' " % (version_raw)) if version_raw_split[0] != "ceph": raise Error("ceph returned an invalid version first value is not ceph:'%s' " % (version_raw)) if version_raw_split[1] != "version": raise Error("ceph returned an invalid version second value is not 'version':'%s' " % (version_raw)) version_public_raw = version_raw_split[2] version_git_raw = version_raw_split[2] version_public = version_public_raw.split(".") if len(version_public) < 3: raise Error("ceph returned an invalid version second value is not 'version':'%s' " % (version_raw)) self.model.ceph_version.major = int(version_public[0]) self.model.ceph_version.minor = int(version_public[1]) self.model.ceph_version.revision = ".".join(version_public[2:]) self.model.ceph_version.uuid = version_raw_split[3].strip("()")
def _remove_rgw_keyring(self): self._set_rgw_path_lib() if not os.path.isdir(self.rgw_path_lib): return rgw_path_keyring = os.path.join(self.rgw_path_lib, 'keyring') path_bootstrap_keyring = keyring._get_path_keyring_rgw(self.model.cluster_name) arguments = [ 'ceph', '--connect-timeout', '5', '--cluster', self.model.cluster_name, '--name', 'client.bootstrap-rgw', '--keyring', path_bootstrap_keyring, 'auth', 'del', 'client.{name}'.format(name=self.rgw_name), ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) )
def pool_list(self): prefix_arguments = [ constants._path_ceph ] postfix_arguments = [ "-f", "json", "osd", "lspools" ] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) details = {} for item in json.loads(output["stdout"].strip()): pool_num = item.get("poolnum") pool_name = item.get("poolname") details[pool_name] = {"poolnum" : pool_num } self.model.pool_list = details
def connect(self): keyring_obj = keyring.keyring_facard(self.model) for keytype in ["admin", "osd", "mds", "rgw", "mon"]: log.debug("Trying keyring:%s" % (keytype)) keyring_obj.key_type = keytype keyring_path = keyring_obj.keyring_path_get() if not os.path.isfile(keyring_path): log.debug("Skipping keyring %s" % (keyring_path)) continue keyring_identity = keyring_obj.keyring_identity_get() arguments = [ constants._path_ceph, '--connect-timeout', '5', "--keyring", keyring_path, "--name", keyring_identity, "-f", "json-pretty", "status" ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: continue self.model.cluster_status = json.loads(output["stdout"].strip()) self.keyring_type = keytype self.keyring_path = keyring_path self.keyring_identity = keyring_identity return True return False
def _pool_adder(self, name, **kwargs): pg_num = kwargs.get("pg_num", 8) pgp_num = kwargs.get("pgp_num", pg_num) pool_type = kwargs.get("pool_type") er_profile = kwargs.get("erasure_code_profile") crush_ruleset_name = kwargs.get("crush_ruleset") prefix_arguments = [ constants._path_ceph ] postfix_arguments = [ 'osd', 'pool', 'create', name, str(pg_num) ] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments if pgp_num is not None: arguments.append(str(pgp_num)) if pool_type == "replicated": arguments.append("replicated") if pool_type == "erasure": arguments.append("erasure") arguments.append("erasure-code-profile=%s" % (er_profile)) if crush_ruleset_name is not None: arguments.append(crush_ruleset_name) output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def lsblk_version_refresh(self): """ Get lsblk version as this is older on RHEL 7.2 """ arguments = [ constants._path_lsblk, "--version" ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] )) version_str = output["stdout"].strip() version_list = shlex.split(version_str) if len(version_list) < 4: raise Error("Failed processing lsblk version string '%s'" % (version_str)) version_split = version_list[3].split(".") self.model.lsblk_version.major = int(version_split[0]) if len(version_split) > 1: self.model.lsblk_version.minor = int(version_split[1]) if len(version_split) > 2: self.model.lsblk_version.revision = int(version_split[2]) else: self.model.lsblk_version.revision = 0
def status_refresh(self): """ Get the cluster status This is not normally needed as connect method has updated this information """ prefix_arguments = [ constants._path_ceph ] postfix_arguments = [ "-f", "json-pretty", "status" ] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) self.model.cluster_status = json.loads(output["stdout"].strip())
def _pool_adder(self, name, **kwargs): pg_num = kwargs.get("pg_num", 8) pgp_num = kwargs.get("pgp_num", pg_num) pool_type = kwargs.get("pool_type") er_profile = kwargs.get("erasure_code_profile") crush_ruleset_name = kwargs.get("crush_ruleset") prefix_arguments = [constants._path_ceph] postfix_arguments = ['osd', 'pool', 'create', name, str(pg_num)] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments if pgp_num is not None: arguments.append(str(pgp_num)) if pool_type == "replicated": arguments.append("replicated") if pool_type == "erasure": arguments.append("erasure") arguments.append("erasure-code-profile=%s" % (er_profile)) if crush_ruleset_name is not None: arguments.append(crush_ruleset_name) output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def partition_table_refresh(self): for disk_name in self.model.lsblk.keys(): arguments = [ 'parted', disk_name, 'print' ] log.debug("Running:%s" % (" ".join(arguments))) output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] )) part_type = None for line in output["stdout"].split('\n'): split_line = line.split(':') if split_line[0] != 'Partition Table': continue part_type = ":".join(split_line[1:]).strip() if part_type is None: continue self.model.lsblk[disk_name]["PARTTABLE"] = part_type
def _execute(self,arguments): prefix = [ "sudo", "-u", "ceph" ] return utils.execute_local_command(prefix + arguments)
def auth_del(self, **kwargs): """ Remove Authorised keyring """ self.model.kargs_apply(**kwargs) u = mdl_updater.model_updater(m) u.hostname_refresh() if m.cluster_name == None: u.defaults_refresh() self.cluster_name = m.cluster_name u.load_confg(m.cluster_name) u.mon_members_refresh() q = mdl_query.mdl_query(m) if not q.mon_is(): raise Error("Not ruining a mon daemon") u.mon_status() if not q.mon_quorum(): raise Error("mon daemon is not in quorum") arguments = [ "ceph", "auth", "del", self.keyring_name ] cmd_out = utils.execute_local_command(arguments) return True
def _remove_mds_keyring(self): if not os.path.isdir(self.mds_path_lib): return mds_path_keyring = os.path.join(self.mds_path_lib, 'keyring') path_bootstrap_keyring = keyring._get_path_keyring_mds( self.model.cluster_name) arguments = [ 'ceph', '--connect-timeout', '5', '--cluster', self.model.cluster_name, '--name', 'client.bootstrap-mds', '--keyring', path_bootstrap_keyring, 'auth', 'del', 'client.{name}'.format(name=self.mds_name), ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def retrive_osd_details(device_name): osd_details = {} if device_name is None: return None try: tmpd = tempfile.mkdtemp() log.info("Create temp directory %s" % (tmpd)) try: out_mnt = utils.execute_local_command(['mount', device_name, tmpd]) if out_mnt['retcode'] == 0: osd_details = _retrive_osd_details_from_dir(tmpd) finally: utils.execute_local_command(['umount', tmpd]) finally: log.info("Destroy temp directory %s" % (tmpd)) os.rmdir(tmpd) return osd_details
def zap(dev=None, **kwargs): """ Destroy the partition table and content of a given disk. """ if dev is not None: log.warning("Depricated use of function, use kwargs") dev = kwargs.get("dev", dev) if dev == None: raise Error('Cannot find', dev) if not os.path.exists(dev): raise Error('Cannot find', dev) dmode = os.stat(dev).st_mode mdl = model.model(**kwargs) osdc = osd.osd_ctrl(mdl) if not stat.S_ISBLK(dmode) or osdc.is_partition(dev): raise Error('not full block device; cannot zap', dev) try: log.debug('Zapping partition table on %s', dev) # try to wipe out any GPT partition table backups. sgdisk # isn't too thorough. lba_size = 4096 size = 33 * lba_size with file(dev, 'wb') as dev_file: dev_file.seek(-size, os.SEEK_END) dev_file.write(size * '\0') utils.execute_local_command([ constants._path_sgdisk, '--zap-all', '--', dev, ], ) utils.execute_local_command([ constants._path_sgdisk, '--clear', '--mbrtogpt', '--', dev, ], ) _update_partition('-d', dev, 'zapped') except subprocess.CalledProcessError as e: raise Error(e) return True
def restart(self, **kwargs): systemctl_name = self._get_systemctl_name(**kwargs) arguments = [constants._path_systemctl, 'restart', systemctl_name] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise init_exception_service( "failed to restart '%s' Error rc=%s, stdout=%s stderr=%s" % (systemctl_name, output["retcode"], output["stdout"], output["stderr"])) return True
def zap(dev): """ Destroy the partition table and content of a given disk. """ dmode = os.stat(dev).st_mode osdc = osd.osd_ctrl() if not stat.S_ISBLK(dmode) or osdc.is_partition(dev): raise Error('not full block device; cannot zap', dev) try: log.debug('Zapping partition table on %s', dev) # try to wipe out any GPT partition table backups. sgdisk # isn't too thorough. lba_size = 4096 size = 33 * lba_size with file(dev, 'wb') as dev_file: dev_file.seek(-size, os.SEEK_END) dev_file.write(size*'\0') utils.execute_local_command( [ constants._path_sgdisk, '--zap-all', '--', dev, ], ) utils.execute_local_command( [ constants._path_sgdisk, '--clear', '--mbrtogpt', '--', dev, ], ) _update_partition('-d', dev, 'zapped') except subprocess.CalledProcessError as e: raise Error(e) return True
def service_shutdown_ceph(): arguments = [ constants._path_systemctl, "stop", "ceph*", ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def auth_del(self, **kwargs): """ Remove Authorised keyring """ keyringobj = keyring.keyring_facard(self.model) keyringobj.key_type = keyring_type q = mdl_query.mdl_query(self.model) if q.mon_is() and q.mon_quorum() is False: raise Error("mon daemon is not in quorum") arguments = ["ceph", "auth", "del", keyringobj.keyring_path_get()] cmd_out = utils.execute_local_command(arguments) return True
def service_shutdown_ceph(): arguments = [ constants._path_systemctl, "stop", "ceph*", ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] ))
def _create_monmap(self, path_monmap): """ create_monmap file """ if not os.path.isfile(path_monmap): arguments = [ "monmaptool", "--create", "--fsid", self.model.cluster_uuid, path_monmap ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) for name, addr in self.model.mon_members: arguments = [ "monmaptool", "--add", name, addr, path_monmap ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) return True
def restart(self, **kwargs): systemctl_name = self._get_systemctl_name(**kwargs) arguments = [ util_which.which_systemctl.path, 'restart', systemctl_name ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise init_exception_service("failed to restart '%s' Error rc=%s, stdout=%s stderr=%s" % ( systemctl_name, output["retcode"], output["stdout"], output["stderr"]) ) return True
def prepare(self): # Due to the way keyring profiles work and the init scripts for rgw we need to # force users to only create rgw with a 'rgw.' prefix. The reason we dont hide # this from the user is due to both the systemd files and rgw deployments may # exist without the prefix if the bootstrap keyring was not used in the key # creation for the rgw service. if not self.rgw_name.startswith("rgw."): raise Error("rgw name must start with 'rgw.'") missing_pools = self.rgw_pools_missing() if len(missing_pools) > 0: raise Error("Pools missing: %s" % (", ".join(missing_pools))) self.service_available() self._set_rgw_path_lib() path_bootstrap_keyring = keyring._get_path_keyring_rgw(self.model.cluster_name) if not os.path.isfile(path_bootstrap_keyring): raise Error("Keyring not found at %s" % (path_bootstrap_keyring)) if not os.path.isdir(self.rgw_path_lib): log.info("Make missing directory:%s" % (self.rgw_path_lib)) os.makedirs(self.rgw_path_lib) rgw_path_keyring = os.path.join(self.rgw_path_lib, 'keyring') if not os.path.isfile(rgw_path_keyring): log.info("Make missing keyring:%s" % (rgw_path_keyring)) arguments = [ 'ceph', '--connect-timeout', '5', '--cluster', self.model.cluster_name, '--name', 'client.bootstrap-rgw', '--keyring', path_bootstrap_keyring, 'auth', 'get-or-create', 'client.{name}'.format(name=self.rgw_name), 'osd', 'allow rwx', 'mon', 'allow rw', '-o', rgw_path_keyring ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: if os.path.isfile(rgw_path_keyring): log.info("Cleaning up new key:%s" % (rgw_path_keyring)) os.remove(rgw_path_keyring) raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) )
def pool_del(self, name): if not name in self.model.pool_list.keys(): return True prefix_arguments = [constants._path_ceph] postfix_arguments = [ 'osd', 'pool', 'delete', name, name, '--yes-i-really-really-mean-it' ] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) return True
def pool_list(self): prefix_arguments = [constants._path_ceph] postfix_arguments = ["-f", "json", "osd", "lspools"] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) details = {} for item in json.loads(output["stdout"].strip()): pool_num = item.get("poolnum") pool_name = item.get("poolname") details[pool_name] = {"poolnum": pool_num} self.model.pool_list = details
def auth_del(self, **kwargs): """ Remove Authorised keyring """ keyringobj = keyring.keyring_facard(self.model) keyringobj.key_type = keyring_type q = mdl_query.mdl_query(self.model) if q.mon_is() and q.mon_quorum() is False: raise Error("mon daemon is not in quorum") arguments = [ "ceph", "auth", "del", keyringobj.keyring_path_get() ] cmd_out = utils.execute_local_command(arguments) return True
def auth_list(self): prefix_arguments = [ constants._path_ceph ] postfix_arguments = [ "auth", "list" ] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) auth_list_out = {} section = {} for line in output["stdout"].split('\n'): if len(line) == 0: continue if line[0] != '\t': prev_sec_name = section.get("name") if prev_sec_name is not None: auth_list_out[prev_sec_name] = section section = { "name" : line } continue tokenised_line = shlex.split(line) if len(tokenised_line) == 0: continue if tokenised_line[0] == 'key:': section['key'] = tokenised_line[1] if tokenised_line[0] == 'caps:': if not 'caps' in section: section['caps'] = [] cap_details = tokenised_line[1:] section["caps"].append(cap_details) prev_sec_name = section.get("name") if prev_sec_name is not None: auth_list_out[prev_sec_name] = section self.model.auth_list = auth_list_out
def mon_status(self): if self.model.hostname is None: raise Error("Hostname not set") if self.model.cluster_name is None: raise Error("cluster_name not set") arguments = [ "ceph", "--cluster=%s" % (self.model.cluster_name), "--admin-daemon", "/var/run/ceph/ceph-mon.%s.asok" % (self.model.hostname), "mon_status" ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) self.model.mon_status = json.loads(output['stdout'])
def auth_add(self, keyring_type): """ Authorise keyring """ keyringobj = keyring.keyring_facard(self.model) keyringobj.key_type = keyring_type if not keyringobj.present(): raise Error("rgw keyring not found") q = mdl_query.mdl_query(self.model) if q.mon_is() and q.mon_quorum() is False: raise Error("mon daemon is not in quorum") arguments = [ "ceph", "auth", "import", "-i", keyringobj.keyring_path_get() ] cmd_out = utils.execute_local_command(arguments) return True
def status_refresh(self): """ Get the cluster status This is not normally needed as connect method has updated this information """ prefix_arguments = [constants._path_ceph] postfix_arguments = ["-f", "json-pretty", "status"] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) self.model.cluster_status = json.loads(output["stdout"].strip())
def partition_table_refresh(self): for disk_name in self.model.lsblk.keys(): arguments = ['parted', disk_name, 'print'] log.debug("Running:%s" % (" ".join(arguments))) output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) part_type = None for line in output["stdout"].split('\n'): split_line = line.split(':') if split_line[0] != 'Partition Table': continue part_type = ":".join(split_line[1:]).strip() if part_type is None: continue self.model.lsblk[disk_name]["PARTTABLE"] = part_type
def partitions_all_refresh(self): ''' List all partition details CLI Example: salt '*' sesceph.partitions_all ''' part_map = {} cmd = [constants._path_lsblk] + self._lsblk_arguements() output = utils.execute_local_command(cmd) if output['retcode'] != 0: raise Error("Failed running: lsblk --ascii --output-all") all_parts = {} for line in output['stdout'].split('\n'): partition = {} for token in shlex.split(line): token_split = token.split("=") if len(token_split) == 1: continue key = token_split[0] value = "=".join(token_split[1:]) if len(value) == 0: continue partition[key] = value part_name = partition.get("NAME") if part_name is None: continue part_type = partition.get("TYPE") if part_type == "disk": all_parts[part_name] = partition continue disk_name = partition.get("PKNAME") if not disk_name in all_parts: continue part_map[part_name] = disk_name if None == all_parts[disk_name].get("PARTITION"): all_parts[disk_name]["PARTITION"] = {} all_parts[disk_name]["PARTITION"][part_name] = partition self.model.lsblk = all_parts self.model.part_pairent = part_map
def create(self, secret=None): """ Create keyring """ keyring_path = self.get_path_keyring() if os.path.isfile(keyring_path): return _keying_read(keyring_path) try: tmpd = tempfile.mkdtemp() key_path = os.path.join(tmpd, "keyring") arguments = self.get_arguments_create(key_path, secret) cmd_out = utils.execute_local_command(arguments) if cmd_out["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), cmd_out["retcode"], cmd_out["stdout"], cmd_out["stderr"])) output = _keying_read(key_path) finally: shutil.rmtree(tmpd) return output
def write_secret(self, secret): """ Persist keyring """ keyring_path = self.get_path_keyring() if os.path.isfile(keyring_path): return True if secret is None: raise Error("Keyring secret is invalid") keyring_dir = os.path.dirname(keyring_path) if not os.path.isdir(keyring_dir): os.makedirs(keyring_dir) arguments = self.get_arguments_create(keyring_path, secret) cmd_out = utils.execute_local_command(arguments) if cmd_out["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), cmd_out["retcode"], cmd_out["stdout"], cmd_out["stderr"])) output = _keying_read(keyring_path) return True
def auth_list(self): prefix_arguments = [constants._path_ceph] postfix_arguments = ["auth", "list"] connection_arguments = self.connection_arguments_get() arguments = prefix_arguments + connection_arguments + postfix_arguments output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) auth_list_out = {} section = {} for line in output["stdout"].split('\n'): if len(line) == 0: continue if line[0] != '\t': prev_sec_name = section.get("name") if prev_sec_name is not None: auth_list_out[prev_sec_name] = section section = {"name": line} continue tokenised_line = shlex.split(line) if len(tokenised_line) == 0: continue if tokenised_line[0] == 'key:': section['key'] = tokenised_line[1] if tokenised_line[0] == 'caps:': if not 'caps' in section: section['caps'] = [] cap_details = tokenised_line[1:] section["caps"].append(cap_details) prev_sec_name = section.get("name") if prev_sec_name is not None: auth_list_out[prev_sec_name] = section self.model.auth_list = auth_list_out
def lsblk_version_refresh(self): """ Get lsblk version as this is older on RHEL 7.2 """ arguments = [constants._path_lsblk, "--version"] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"])) version_str = output["stdout"].strip() version_list = shlex.split(version_str) if len(version_list) < 4: raise Error("Failed processing lsblk version string '%s'" % (version_str)) version_split = version_list[3].split(".") self.model.lsblk_version.major = int(version_split[0]) if len(version_split) > 1: self.model.lsblk_version.minor = int(version_split[1]) if len(version_split) > 2: self.model.lsblk_version.revision = int(version_split[2]) else: self.model.lsblk_version.revision = 0
def unmount_osd(self): for part in self.model.partitions_osd: disk = self.model.part_pairent.get(part) if disk is None: continue disk_details = self.model.lsblk.get(disk) if disk_details is None: continue all_parts = disk_details.get('PARTITION') if all_parts is None: continue part_details = all_parts.get(part) if part_details is None: continue mountpoint = part_details.get("MOUNTPOINT") if mountpoint is None: continue arguments = ["umount", mountpoint] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error( "Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % (" ".join(arguments), output["retcode"], output["stdout"], output["stderr"]))
def _execute(self, arguments): return utils.execute_local_command(arguments)
def create(self, **kwargs): """ Create a mon node CLI Example: salt '*' sesceph.prepare 'cluster_name'='ceph' \ 'cluster_uuid'='cluster_uuid' \ Notes: cluster_uuid Set the cluster UUID. Defaults to value found in ceph config file. cluster_name Set the cluster name. Defaults to "ceph". """ u = mdl_updater.model_updater(self.model) u.hostname_refresh() u.defaults_refresh() u.load_confg(self.model.cluster_name) u.mon_members_refresh() q = mdl_query.mdl_query(self.model) if not q.mon_is(): raise Error("Not a mon node") p = presenter.mdl_presentor(self.model) path_done_file = "/var/lib/ceph/mon/%s-%s/done" % ( self.model.cluster_name, self.model.hostname ) keyring_path_mon = keyring._get_path_keyring_mon_bootstrap(self.model.cluster_name, self.model.hostname) path_adm_sock = "/var/run/ceph/%s-mon.%s.asok" % ( self.model.cluster_name, self.model.hostname ) path_mon_dir = "/var/lib/ceph/mon/%s-%s" % ( self.model.cluster_name, self.model.hostname ) path_admin_keyring = keyring._get_path_keyring_admin(self.model.cluster_name) path_monmap = "/var/lib/ceph/tmp/%s.monmap" % ( self.model.cluster_name ) path_tmp_keyring = "/var/lib/ceph/tmp/%s.keyring" % ( self.model.cluster_name ) if os.path.isfile(path_done_file): log.debug("Mon done file exists:%s" % (path_done_file)) if q.mon_active(): return True arguments = [ constants._path_systemctl, "restart", "ceph-mon@%s" % (self.model.hostname) ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"]) ) # Error is servcie wont start if not q.mon_active(): raise Error("Failed to start monitor") return True if not os.path.isfile(keyring_path_mon): raise Error("Mon keyring missing") if not os.path.isfile(path_admin_keyring): raise Error("Admin keyring missing") try: tmpd = tempfile.mkdtemp() log.info("Create temp directory %s" %(tmpd)) os.chown(tmpd, self.uid, self.gid) # In 'tmpd' we make the monmap and keyring. key_path = os.path.join(tmpd,"keyring") path_monmap = os.path.join(tmpd,"monmap") log.info("Create monmap %s" % (path_monmap)) self._create_monmap(path_monmap) os.chown(path_monmap, self.uid, self.gid) arguments = [ constants._path_ceph_authtool, "--create-keyring", key_path, "--import-keyring", keyring_path_mon, ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] )) arguments = [ constants._path_ceph_authtool, key_path, "--import-keyring", path_admin_keyring, ] output = utils.execute_local_command(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] )) # Now chown the new file os.chown(key_path, self.uid, self.gid) # Now clean the install area if os.path.isdir(path_mon_dir): log.info("Remove directory content %s" %(path_mon_dir)) shutil.rmtree(path_mon_dir) if not os.path.isdir(path_mon_dir): log.info("Make directory %s" %(path_mon_dir)) os.makedirs(path_mon_dir) os.chown(path_mon_dir, self.uid, self.gid) # now do install arguments = [ constants._path_ceph_mon, "--mkfs", "-i", self.model.hostname, "--monmap", path_monmap, '--keyring', key_path ] output = self._execute(arguments) if output["retcode"] != 0: raise Error("Failed executing '%s' Error rc=%s, stdout=%s stderr=%s" % ( " ".join(arguments), output["retcode"], output["stdout"], output["stderr"] )) # check keyring created: path_mon_key = os.path.join(path_mon_dir, "keyring") if not os.path.isfile(path_mon_key): raise Error("Failed to create '%s'" % (path_mon_key)) # Now start the service arguments = { 'identifier' : self.model.hostname, 'service' : "ceph-mon", } self.init_system.restart(**arguments) self._create_check_retry() open(path_done_file, 'a').close() finally: log.info("Destroy temp directory %s" %(tmpd)) shutil.rmtree(tmpd) return True
def is_running(self, **kwargs): service_name = self._get_sysvinit_name(**kwargs) arguments = ['chkconfig', service_name, 'status'] utils.execute_local_command(arguments)
def on_boot_disable(self, **kwargs): service_name = self._get_sysvinit_name(**kwargs) arguments = ['chkconfig', service_name, 'off'] utils.execute_local_command(arguments)