def add_item(self, cfg_type, element_name=None, initial_value=None): now = get_time() if element_name: # ensure the initial state for this item has a 'created' date/time value if isinstance(initial_value, dict): if 'created' not in initial_value: initial_value['created'] = now if initial_value is None: init_state = {"created": now} else: init_state = initial_value self.config[cfg_type][element_name] = init_state if isinstance(init_state, str) and 'created' not in self.config[cfg_type]: self.config[cfg_type]['created'] = now # add a separate transaction to capture the creation date to the section txn = ConfigTransaction(cfg_type, 'created', initial_value=now) self.txn_list.append(txn) else: # new section being added to the config object self.config[cfg_type] = initial_value init_state = initial_value txn = ConfigTransaction(cfg_type, None, initial_value=initial_value) self.txn_list.append(txn) self.logger.debug("(Config.add_item) config updated to {}".format(self.config)) self.changed = True txn = ConfigTransaction(cfg_type, element_name, initial_value=init_state) self.txn_list.append(txn)
def update_item(self, cfg_type, element_name, element_value): now = get_time() if element_name: current_values = self.config[cfg_type][element_name] self.logger.debug( "prior to update, item contains {}".format(current_values)) if isinstance(element_value, dict): merged = current_values.copy() new_dict = element_value new_dict['updated'] = now merged.update(new_dict) element_value = merged.copy() self.config[cfg_type][element_name] = element_value else: # update to a root level config element, like version self.config[cfg_type] = element_value self.logger.debug("(Config.update_item) config is {}".format( self.config)) self.changed = True self.logger.debug("update_item: type={}, item={}, update={}".format( cfg_type, element_name, element_value)) txn = ConfigTransaction(cfg_type, element_name, 'add') txn.item_content = element_value self.txn_list.append(txn)
def _commit_rbd(self, post_action): ioctx = self._open_ioctx() if not self.config_locked: self.lock() if self.error: return # reread the config to account for updates made by other systems # then apply this hosts update(s) current_config = json.loads(self._read_config_object(ioctx)) for txn in self.txn_list: self.logger.debug("_commit_rbd transaction shows {}".format(txn)) if txn.action == 'add': # add's and updates if txn.item_name: current_config[txn.type][txn.item_name] = txn.item_content else: current_config[txn.type] = txn.item_content elif txn.action == 'delete': if txn.item_name: del current_config[txn.type][txn.item_name] else: del current_config[txn.type] else: self.error = True self.error_msg = "Unknown transaction type ({}} encountered in " \ "_commit_rbd".format(txn.action) if not self.error: if self.reset: current_config["epoch"] = 0 else: # Python will switch from plain to long int automagically current_config["epoch"] += 1 now = get_time() current_config['updated'] = now config_str = json.dumps(current_config) self.logger.debug( "_commit_rbd updating config to {}".format(config_str)) config_str_fmtd = json.dumps(current_config, sort_keys=True, indent=4, separators=(',', ': ')) ioctx.write_full(self.config_name, config_str_fmtd.encode('utf-8')) ioctx.set_xattr(self.config_name, "epoch", str(current_config["epoch"]).encode('utf-8')) del self.txn_list[:] # empty the list of transactions self.unlock() ioctx.close() if post_action == 'close': self.ceph.shutdown()
def _seed_rbd_config(self): ioctx = self._open_ioctx() self.lock() if self.error: return # if the config object is empty, seed it - if not just leave as is cfg_data = self._read_config_object(ioctx) if not cfg_data: self.logger.debug("_seed_rbd_config found empty config object") seed_now = Config.seed_config seed_now['created'] = get_time() seed = json.dumps(seed_now, sort_keys=True, indent=4, separators=(',', ': ')) ioctx.write_full(self.config_name, seed.encode('utf-8')) ioctx.set_xattr(self.config_name, "epoch", "0".encode('utf-8')) self.changed = True self.unlock()