def run(self): log_debug(2) if self.options.dest_file and self.options.topdir: die(6, "Error: conflicting options --dest-file and --topdir") if len(self.args) == 0: die(0, "No files supplied (use --help for help)") channel = self.options.channel if not channel: die(6, "Config channel not specified") r = self.repository if not r.config_channel_exists(channel): die(6, "Error: config channel %s does not exist" % channel) topdir = self.options.topdir revision = self.options.revision files_to_diff = [] files = map(utils.normalize_path, self.args) files_count = len(files) if files_count != 1 and revision is not None: die(8, "--revision can only be used with a single file") if self.options.dest_file: if files_count != 1: die(7, "--dest-file accepts a single file") files_to_diff.append((files[0], self.options.dest_file)) elif topdir: if not os.path.isdir(topdir): die(8, "--topdir specified, but `%s' not a directory" % topdir) #5/11/04 wregglej - 141790 remove trailing slash in topdir, if present. topdir = utils.rm_trailing_slash(topdir) for f in files: if not f.startswith(topdir): die( 8, "--topdir %s specified, but file `%s' doesn't comply" % (topdir, f)) if os.path.isdir(f) and not os.path.islink(f): die(8, "Cannot diff %s; it is a directory" % f) files_to_diff.append((f, f[len(topdir):])) else: for f in files: if os.path.isdir(f) and not os.path.islink(f): die(8, "Cannot diff %s; it is a directory" % f) files_to_diff.append((f, f)) for (local_file, remote_file) in files_to_diff: sys.stdout.write( self.diff_file(channel, remote_file, local_file, revision))
def mkdir_p(path, mode=None, symlinks=None, allfiles=None): """ Similar to 'mkdir -p' -- makes all directories necessary to ensure the 'path' is a directory, and return the list of directories that were made as a result """ if mode is None: mode = 0700 dirs_created = [] components = path_full_split(path) for i in range(1,len(components)): d = os.path.join(*components[:i+1]) if symlinks: for symlink in symlinks: if symlink['path'] == d: # create symlink and remove it from symlink list os.symlink(symlink['symlink'], symlink['path']) symlinks.remove(symlink) allfiles.remove(symlink) dirs_created.append(symlink) continue log_debug(8, "testing",d) try: os.mkdir(d, mode) except OSError, e: if e.errno != 17: raise else: log_debug(8, "created",d) dirs_created.append(d)
def run(self): log_debug(2) r = self.repository files = r.list_files() if not files: die(1, "No managed files.") label = "Config Channel" maxlen = max(map(lambda s: len(s[0]), files)) maxlen = max(maxlen, len(label)) + 2 print "%-10s %8s %-8s %10s %+3s %*s %s" % ('Mode', 'Owner', 'Group', 'Size', 'Rev', maxlen, label, "File") for file in files: # Get the file info finfo = r.get_file_info(file[1])[1] # Get the file length if finfo['encoding'] == 'base64': fsize = len(base64.decodestring(finfo['file_contents'])) else: # * indicates raw 'unencoded' size fsize = '*' + str(len(finfo['file_contents'])) permstr = finfo['filetype'] != 'symlink' and self.ostr_to_sym(finfo['filemode'], finfo['filetype']) or '' dest = finfo['filetype'] != 'symlink' and file[1] or "%s -> %s" % (file[1], finfo['symlink']) print "%10s %8s %-8s %10s %+3s %*s %s" % (permstr, finfo['username'], finfo['groupname'], fsize, finfo['revision'], maxlen, file[0], dest)
def run(self): log_debug(2) r = self.repository files = r.list_files() if not files: die(1, "No managed files.") label = "Config Channel" maxlen = max(map(lambda s: len(s[0]), files)) maxlen = max(maxlen, len(label)) + 2 print "DoFoS %*s %s" % (maxlen, label, "File") arg_files = [] if len(sys.argv) > 2: arg_files = sys.argv[2:len(sys.argv)] for file in files: if len(arg_files) and not file[1] in arg_files: continue # checking to see if the filetype is in the 'file' entry, # and if it is and that type is '1', it is a file if (len(file) < 3) or file[2] == 1: print "F %*s %s" % (maxlen, file[0], file[1]) elif file[2] == 2: # the filetype is a directory print "D %*s %s" % (maxlen, file[0], file[1]) else: print "S %*s %s" % (maxlen, file[0], file[1])
def get_file_info(self, file, auto_delete=1, dest_directory=None): log_debug(4, file) result = self.rpc_call('config.client.get_file', self.system_id, file) if 'missing' in result: return None dirs_created = None # Older servers will not return directories; if filetype is missing, # assume file if result.get('filetype') == 'directory': if dest_directory: result['path'] = dest_directory.rstrip(os.path.sep) + result['path'] if os.path.isfile(result['path']): raise cfg_exceptions.DirectoryEntryIsFile(result['path']) else: auto_delete = 0 temp_file = result['path'] else: f = file_utils.FileProcessor() temp_file, dirs_created = f.process(result, directory=dest_directory) if auto_delete: self.files_to_delete.append(temp_file) return temp_file, result, dirs_created
def mkdir_p(path, mode=None, symlinks=None, allfiles=None): """ Similar to 'mkdir -p' -- makes all directories necessary to ensure the 'path' is a directory, and return the list of directories that were made as a result """ if mode is None: mode = 0700 dirs_created = [] components = path_full_split(path) for i in range(1, len(components)): d = os.path.join(*components[:i + 1]) if symlinks: for symlink in symlinks: if symlink['path'] == d: # create symlink and remove it from symlink list os.symlink(symlink['symlink'], symlink['path']) symlinks.remove(symlink) allfiles.remove(symlink) dirs_created.append(symlink) continue log_debug(8, "testing", d) try: os.mkdir(d, mode) except OSError, e: if e.errno != 17: raise else: log_debug(8, "created", d) dirs_created.append(d)
def diff_file_revisions(self, path, config_channel_src, revision_src, config_channel_dst, revision_dst): log_debug(4) params = { 'session' : self.session, 'path' : path, 'config_channel_src': config_channel_src, 'revision_src' : revision_src, } if config_channel_dst is not None: params['config_channel_dst'] = config_channel_dst if revision_dst is not None: params['revision_dst'] = revision_dst try: ret = self.rpc_call('config.management.diff', params) except xmlrpclib.Fault: e = sys.exc_info()[1] if e.faultCode == -4011: # File not present raise_with_tb(cfg_exceptions.RepositoryFileMissingError(e.faultString), sys.exc_info()[2]) if e.faultCode == -4004: # Binary file requested raise_with_tb(cfg_exceptions.BinaryFileDiffError(e.faultString), sys.exc_info()[2]) raise return ret
def diff_file_revisions(self, path, config_channel_src, revision_src, config_channel_dst, revision_dst): log_debug(4) params = { 'session': self.session, 'path': path, 'config_channel_src': config_channel_src, 'revision_src': revision_src, } if config_channel_dst is not None: params['config_channel_dst'] = config_channel_dst if revision_dst is not None: params['revision_dst'] = revision_dst try: ret = self.rpc_call('config.management.diff', params) except xmlrpclib.Fault: e = sys.exc_info()[1] if e.faultCode == -4011: # File not present raise_with_tb( cfg_exceptions.RepositoryFileMissingError(e.faultString), sys.exc_info()[2]) if e.faultCode == -4004: # Binary file requested raise_with_tb( cfg_exceptions.BinaryFileDiffError(e.faultString), sys.exc_info()[2]) raise return ret
def run(self): log_debug(2) r = self.repository if not self.args: die(6, "No config channels specified") topdir = self.options.topdir if not topdir: die(7, "--topdir not specified") if not os.path.isdir(topdir): die(8, "--topdir specified, but `%s' not a directory" % topdir) for ns in self.args: if not r.config_channel_exists(ns): die(6, "Error: config channel %s does not exist" % ns) for file_path in r.list_files(ns): #5/11/05 wregglej - 157066 dirs_created now gets returned by get_file_info. (temp_file, info, dirs_created) = r.get_file_info(ns, file_path) dest_file = utils.join_path(topdir, ns, file_path) print "Deploying %s -> %s" % (file_path, dest_file) utils.copyfile_p(temp_file, dest_file) if info['filetype'] != 'symlink': utils.set_file_info(dest_file, info)
def get_file_info(self, file, auto_delete=1, dest_directory=None): log_debug(4, file) result = self.rpc_call('config.client.get_file', self.system_id, file) if 'missing' in result: return None dirs_created = None # Older servers will not return directories; if filetype is missing, # assume file if result.get('filetype') == 'directory': if dest_directory: result['path'] = dest_directory.rstrip( os.path.sep) + result['path'] if os.path.isfile(result['path']): raise cfg_exceptions.DirectoryEntryIsFile(result['path']) else: auto_delete = 0 temp_file = result['path'] else: f = file_utils.FileProcessor() temp_file, dirs_created = f.process(result, directory=dest_directory) if auto_delete: self.files_to_delete.append(temp_file) return temp_file, result, dirs_created
def add_preprocessed(self, dest_path, processed_file_path, file_info, dirs_created, strict_ownership=1): """preprocess the file if needed, and add the entry to the correct list""" dest_path = self._normalize_path_to_root(dest_path) log_debug(3, "preprocessing entry") # If we get any dirs that were created by mkdir_p, add them here if dirs_created: self.new_dirs.extend(dirs_created) # If the file is a directory, don't do all the file related work # Older servers will not return directories; if filetype is missing, # assume file if file_info.get('filetype') == 'directory': self.dirs.append(file_info) else: if "dest_path" in self.newtemp_by_path: raise DuplicateDeployment( "Error: %s already added to transaction" % dest_path) self.newtemp_by_path[dest_path] = processed_file_path self._chown_chmod_chcon(processed_file_path, dest_path, file_info, strict_ownership=strict_ownership)
def run(self): log_debug(2) r = self.repository files = r.list_files() if not files: die(1, "No managed files.") label = "Config Channel" maxlen = max(map(lambda s: len(s[0]), files)) maxlen = max(maxlen, len(label)) + 2 print "DoFoS %*s %s" % (maxlen, label, "File") arg_files = [] if len(sys.argv) > 2: arg_files = sys.argv[2:len(sys.argv)] for file in files: if len(arg_files) and not file[1] in arg_files: continue # checking to see if the filetype is in the 'file' entry, # and if it is and that type is '1', it is a file if (len(file) < 3) or file[2] == 1: print "F %*s %s" % (maxlen, file[0], file[1]) elif file[2] == 2 : # the filetype is a directory print "D %*s %s" % (maxlen, file[0], file[1]) else: print "S %*s %s" % (maxlen, file[0], file[1])
def run(self): log_debug(2) if self.options.dest_file and self.options.topdir: die(6, "Error: conflicting options --dest-file and --topdir") if len(self.args) == 0: die(0, "No files supplied (use --help for help)") channel = self.options.channel if not channel: die(6, "Config channel not specified") r = self.repository if not r.config_channel_exists(channel): die(6, "Error: config channel %s does not exist" % channel) topdir = self.options.topdir revision = self.options.revision files_to_diff = [] files = [utils.normalize_path(x) for x in self.args] files_count = len(files) if files_count != 1 and revision is not None: die(8, "--revision can only be used with a single file") if self.options.dest_file: if files_count != 1: die(7, "--dest-file accepts a single file") files_to_diff.append((files[0], self.options.dest_file)) elif topdir: if not os.path.isdir(topdir): die(8, "--topdir specified, but `%s' not a directory" % topdir) #5/11/04 wregglej - 141790 remove trailing slash in topdir, if present. topdir = utils.rm_trailing_slash(topdir) for f in files: if not f.startswith(topdir): die(8, "--topdir %s specified, but file `%s' doesn't comply" % (topdir, f)) if os.path.isdir(f) and not os.path.islink(f): die(8, "Cannot diff %s; it is a directory" % f) files_to_diff.append((f, f[len(topdir):])) else: for f in files: if os.path.isdir(f) and not os.path.islink(f): die(8, "Cannot diff %s; it is a directory" % f) files_to_diff.append((f, f)) for (local_file, remote_file) in files_to_diff: sys.stdout.write( self.diff_file(channel, remote_file, local_file, revision))
def put_files(self, action_id, files, upload_contents=1): """Inserts a set of files into the repo, as a result of a scheduled action""" log_debug(4) missing_files = [] files_too_large = [] failed_due_to_quota = [] max_file_size = self.get_maximum_file_size() for file in files: try: params = self._make_file_info(file, local_path=None, load_contents=upload_contents) except cfg_exceptions.RepositoryLocalFileError: missing_files.append(file) continue if upload_contents and (params['size'] > max_file_size): files_too_large.append(file) continue try: self.rpc_call('config.client.upload_file', self.system_id, action_id, params) except xmlrpclib.Fault: e = sys.exc_info()[1] fault_code, fault_string = e.faultCode, e.faultString # deal with particular faults if fault_code == -4003: # File too large files_too_large.append(file) elif fault_code == -4014: # Ran out of org quota space failed_due_to_quota.append(file) else: raise_with_tb( cfg_exceptions.RepositoryFilePushError( fault_code, fault_string), sys.exc_info()[2]) except Exception: traceback.print_exc() raise result = {} # If there are files too large to be pushed, result will have a key # `file_too_large' if len(files_too_large) > 0: result['files_too_large'] = files_too_large if len(failed_due_to_quota) > 0: result['failed_due_to_quota'] = failed_due_to_quota if len(missing_files) > 0: result['missing_files'] = missing_files return result
def remove_file(self, config_channel, repopath): """ remove a given file from the repo """ log_debug(4) params = { 'session': self.session, 'config_channel': config_channel, 'path': repopath, } return self.rpc_call('config.management.remove_file', params)
def remove_file(self, config_channel, repopath): """ remove a given file from the repo """ log_debug(4) params = { 'session' : self.session, 'config_channel' : config_channel, 'path' : repopath, } return self.rpc_call('config.management.remove_file', params)
def __init__(self, setup_network=1): log_debug(2) repository.RPC_Repository.__init__(self, setup_network) self.files_to_delete = [] self.username = None self.password = None self.session = None
def list_files(self, config_channel, repopath = None, recurse = 1): """ list files in a repo, recursing if requested; repopath is not used yet """ log_debug(4) files = self.rpc_call('config.management.list_files', {'session' : self.session, 'config_channel' : config_channel}) return map(lambda p: p['path'], files)
def create_config_channel(self, config_channel): "creates a configuration channel" log_debug(4, config_channel) try: return self.rpc_call('config.management.create_config_channel', {'session' : self.session, 'config_channel' : config_channel}) except repository.rpclib.Fault, e: if e.faultCode == -4010: raise cfg_exceptions.ConfigChannelAlreadyExistsError(config_channel) raise
def run(self): log_debug(2) r = self.repository if len(self.args): die(5, "No arguments required") print("Available config channels:") for ns in r.list_config_channels(): print(" %s" % ns)
def put_files(self, action_id, files, upload_contents=1): """Inserts a set of files into the repo, as a result of a scheduled action""" log_debug(4) missing_files = [] files_too_large = [] failed_due_to_quota = [] max_file_size = self.get_maximum_file_size() for file in files: try: params = self._make_file_info(file, local_path=None, load_contents=upload_contents) except cfg_exceptions.RepositoryLocalFileError: missing_files.append(file) continue if upload_contents and (params['size'] > max_file_size): files_too_large.append(file) continue try: self.rpc_call('config.client.upload_file', self.system_id, action_id, params) except xmlrpclib.Fault: e = sys.exc_info()[1] fault_code, fault_string = e.faultCode, e.faultString # deal with particular faults if fault_code == -4003: # File too large files_too_large.append(file) elif fault_code == -4014: # Ran out of org quota space failed_due_to_quota.append(file) else: raise_with_tb(cfg_exceptions.RepositoryFilePushError(fault_code, fault_string), sys.exc_info()[2]) except Exception: traceback.print_exc() raise result = {} # If there are files too large to be pushed, result will have a key # `file_too_large' if len(files_too_large) > 0: result['files_too_large'] = files_too_large if len(failed_due_to_quota) > 0: result['failed_due_to_quota'] = failed_due_to_quota if len(missing_files) > 0: result['missing_files'] = missing_files return result
def list_config_channels(self): "List config channels" log_debug(4) if hasattr(self, 'config_channels'): return self.config_channels self.config_channels = self.rpc_call( 'config.management.list_config_channels', {'session' : self.session} ) or [] return self.config_channels
def put_file(self, config_channel, repopath, localfile=None, is_first_revision=None, old_revision=None, delim_start=None, delim_end=None, selinux_ctx=None): """ Insert a given file into the repo, overwriting if necessary. localfile defaults to the repopath """ log_debug(4) params = self._make_file_info(repopath, localfile, delim_start=delim_start, delim_end=delim_end) max_file_size = self.get_maximum_file_size() if params['size'] > max_file_size: error_msg = "%s too large (%s bytes, %s bytes max allowed)" raise cfg_exceptions.ConfigFileTooLargeError(error_msg % (localfile, params['size'], max_file_size)) if selinux_ctx is not None: params.update({ 'selinux_ctx' : selinux_ctx, }) params.update({ 'session' : self.session, 'config_channel' : config_channel, }) if is_first_revision: params['is_first_revision'] = 1 elif old_revision: params['old_revision'] = int(old_revision) try: result = self.rpc_call('config.management.put_file', params) except xmlrpclib.Fault: e = sys.exc_info()[1] fault_code, fault_string = e.faultCode, e.faultString if is_first_revision and fault_code == -4013: raise_with_tb(cfg_exceptions.RepositoryFileExistsError(fault_string), sys.exc_info()[2]) if old_revision and fault_code == -4012: raise_with_tb(cfg_exceptions.RepositoryFileVersionMismatchError(fault_string), sys.exc_info()[2]) if fault_code == -4003: raise_with_tb(cfg_exceptions.ConfigFileTooLargeError(fault_string), sys.exc_info()[2]) if fault_code == -4014: raise_with_tb(cfg_exceptions.QuotaExceeded(fault_string), sys.exc_info()[2]) raise_with_tb(cfg_exceptions.RepositoryFilePushError(fault_code, fault_string), sys.exc_info()[2]) return result
def list_config_channels(self): "List config channels" log_debug(4) if hasattr(self, 'config_channels'): return self.config_channels self.config_channels = self.rpc_call( 'config.management.list_config_channels', {'session': self.session}) or [] return self.config_channels
def create_config_channel(self, config_channel): "creates a configuration channel" log_debug(4, config_channel) try: return self.rpc_call('config.management.create_config_channel', {'session' : self.session, 'config_channel' : config_channel}) except xmlrpclib.Fault: e = sys.exc_info()[1] if e.faultCode == -4010: raise_with_tb(cfg_exceptions.ConfigChannelAlreadyExistsError(config_channel), sys.exc_info()[2]) raise
def remove_config_channel(self, config_channel): "Removes a configuration channel" log_debug(4, config_channel) try: return self.rpc_call('config.management.remove_config_channel', {'session' : self.session, 'config_channel' : config_channel}) except repository.rpclib.Fault, e: if e.faultCode == -4009: raise cfg_exceptions.ConfigChannelNotInRepo(config_channel) if e.faultCode == -4005: raise cfg_exceptions.ConfigChannelNotEmptyError(config_channel) raise
def list_files(self, config_channel, repopath=None, recurse=1): """ list files in a repo, recursing if requested; repopath is not used yet """ log_debug(4) files = self.rpc_call('config.management.list_files', { 'session': self.session, 'config_channel': config_channel }) return [p['path'] for p in files]
def create_config_channel(self, config_channel): "creates a configuration channel" log_debug(4, config_channel) try: return self.rpc_call('config.management.create_config_channel', { 'session': self.session, 'config_channel': config_channel }) except xmlrpclib.Fault, e: if e.faultCode == -4010: raise cfg_exceptions.ConfigChannelAlreadyExistsError( config_channel), None, sys.exc_info()[2] raise
def remove_config_channel(self, config_channel): "Removes a configuration channel" log_debug(4, config_channel) try: return self.rpc_call('config.management.remove_config_channel', {'session' : self.session, 'config_channel' : config_channel}) except xmlrpclib.Fault: e = sys.exc_info()[1] if e.faultCode == -4009: raise_with_tb(cfg_exceptions.ConfigChannelNotInRepo(config_channel), sys.exc_info()[2]) if e.faultCode == -4005: raise_with_tb(cfg_exceptions.ConfigChannelNotEmptyError(config_channel), sys.exc_info()[2]) raise
def run(self): log_debug(2) for file in self.get_valid_files(): (src, file_info, dirs_created) = self.repository.get_file_info(file) ftype = file_info.get('filetype') if not src: continue dst = self.get_dest_file(file) self._process_file(src, dst, file, ftype, file_info)
def run(self): log_debug(2) r = self.repository if len(self.args) != 1: die(3, "One file needs to be specified") path = self.args[0] channel_dst = None ns_count = len(self.options.channel or []) if ns_count == 0: die(3, "At least one config channel has to be specified") channel_src = self.options.channel[0] if ns_count > 2: die(3, "At most two config channels can be specified") if not r.config_channel_exists(channel_src): die(4, "Source config channel %s does not exist" % channel_src) if ns_count == 2: channel_dst = self.options.channel[1] if not r.config_channel_exists(channel_dst): die(4, "Config channel %s does not exist" % channel_dst) revision_dst = None rev_count = len(self.options.revision or []) if rev_count == 0: die(3, "At least one revision has to be specified") revision_src = self.options.revision[0] if rev_count > 2: die(3, "At most two revisions can be specified") if rev_count == 2: revision_dst = self.options.revision[1] try: result = r.diff_file_revisions(path, channel_src, revision_src, channel_dst, revision_dst) except cfg_exceptions.RepositoryFileMissingError: e = sys.exc_info()[1] die(2, e[0]) except cfg_exceptions.BinaryFileDiffError: e = sys.exc_info()[1] die(3, e[0]) sys.stdout.write(result)
def run(self): log_debug(2) r = self.repository if len(self.args) == 0: die(5, "No config channels specified") for channel in self.args: print "Creating config channel %s" % channel try: r.create_config_channel(channel) except cfg_exceptions.ConfigChannelAlreadyExistsError: die("Config channel %s already exists" % channel) print "Config channel %s created" % channel
def remove_config_channel(self, config_channel): "Removes a configuration channel" log_debug(4, config_channel) try: return self.rpc_call('config.management.remove_config_channel', { 'session': self.session, 'config_channel': config_channel }) except xmlrpclib.Fault, e: if e.faultCode == -4009: raise cfg_exceptions.ConfigChannelNotInRepo( config_channel), None, sys.exc_info()[2] if e.faultCode == -4005: raise cfg_exceptions.ConfigChannelNotEmptyError( config_channel), None, sys.exc_info()[2] raise
def run(self): log_debug(2) r = self.repository config_channels = r.load_config_channels() if not config_channels: print("(no config channels associated with this system)") return print("Config channels:") templ = "%-32s%s" label = "Label" name = "Name" print(templ % (label, name)) print(templ % ('-' * len(label), '-' * len(name))) for c in config_channels: print(templ % (c['label'], c['name']))
def run(self): log_debug(2) r = self.repository config_channels = r.load_config_channels() if not config_channels: print "(no config channels associated with this system)" return print "Config channels:" templ = "%-32s%s" label = "Label" name = "Name" print templ % (label, name) print templ % ("-" * len(label), "-" * len(name)) for c in config_channels: print templ % (c["label"], c["name"])
def run(self): log_debug(2) r = self.repository if len(self.args) == 0: die(0, "No files supplied (use --help for help)") channel = self.options.channel if not channel: die(6, "Config channel not specified") r = self.repository if not r.config_channel_exists(channel): die(6, "Error: config channel %s does not exist" % channel) files = [utils.normalize_path(x) for x in self.args] files_to_remove = [] if self.options.topdir: if not os.path.isdir(self.options.topdir): die( 8, "--topdir specified, but `%s' not a directory" % self.options.topdir) for f in files: if not f.startswith(self.options.topdir): die( 8, "--topdir %s specified, but file `%s' doesn't comply" % (self.options.topdir, f)) files_to_remove.append((f, f[len(self.options.topdir):])) else: for f in files: files_to_remove.append((f, f)) print("Removing from config channel %s" % channel) for (local_file, remote_file) in files_to_remove: try: r.remove_file(channel, remote_file) except xmlrpclib.Fault: e = sys.exc_info()[1] if e.faultCode == -4011: print("%s does not exist" % remote_file) continue raise else: print("%s removed" % remote_file)
def run(self): log_debug(2) r = self.repository if len(self.args) != 1: die(5, "Exactly one argument required") channel = self.args[0] print "Files in config channel '%s':" % channel files = r.list_files(channel) if not files: print "(no files in config channel)" else: for file in files: print " %s" % file
def __init__(self, setup_network=1): repository.RPC_Repository.__init__(self, setup_network) systemid_file = local_config.get("systemid") or self.default_systemid try: f = open(systemid_file, "r") except IOError: e = sys.exc_info()[1] sys.stderr.write("Cannot open %s: %s\n" % (systemid_file, e)) sys.exit(1) self.system_id = f.read() f.close() log_debug(4, 'system id', self.system_id) self.files_to_delete = []
def run(self): log_debug(2) r = self.repository if len(self.args) == 0: die(5, "No config channels specified") for config_channel in self.args: print("Removing config channel %s" % config_channel) try: r.remove_config_channel(config_channel) except cfg_exceptions.ConfigChannelNotInRepo: die("Config channel %s does not exist" % config_channel) except cfg_exceptions.ConfigChannelNotEmptyError: die("Could not remove non-empty config channel %s" % config_channel) print("Config channel %s removed" % config_channel)
def run(self): log_debug(2) r = self.repository if len(self.args) != 1: die(5, "Exactly one argument required") channel = self.args[0] print("Files in config channel '%s':" % channel) files = r.list_files(channel) if not files: print("(no files in config channel)") else: for file in files: print(" %s" % file)
def run(self): log_debug(2) r = self.repository files = r.list_files() if not files: die(1, "No managed files.") label = "Config Channel" maxlen = max(map(lambda s: len(s[0]), files)) maxlen = max(maxlen, len(label)) + 2 print "%-10s %8s %-8s %10s %+3s %*s %s" % ( 'Mode', 'Owner', 'Group', 'Size', 'Rev', maxlen, label, "File") arg_files = [] if len(sys.argv) > 2: arg_files = sys.argv[2:len(sys.argv)] for file in files: if len(arg_files) and not file[1] in arg_files: continue # Get the file info finfo = r.get_file_info(file[1])[1] # Get the file length if finfo['encoding'] == 'base64': fsize = len(base64.decodestring(finfo['file_contents'])) else: # * indicates raw 'unencoded' size fsize = '*' + str(len(finfo['file_contents'])) if finfo['filetype'] == 'symlink': permstr = ostr_to_sym('777', finfo['filetype']) dest = "%s -> %s" % (file[1], finfo['symlink']) fsize = str(len(finfo['symlink'])) finfo['username'] = '******' finfo['groupname'] = 'root' else: permstr = ostr_to_sym(finfo['filemode'], finfo['filetype']) or '' dest = file[1] print "%10s %8s %-8s %10s %+3s %*s %s" % ( permstr, finfo['username'], finfo['groupname'], fsize, finfo['revision'], maxlen, file[0], dest)
def run(self): log_debug(2) #5/12/05 wregglej - 149034 changed r into a instance variable self.r = self.repository topdir = self.options.topdir if not topdir: die(7, "--topdir not specified") if not os.path.isdir(topdir): die(8, "--topdir specified, but `%s' not a directory" % topdir) topdir = utils.normalize_path(topdir) #5/12/05 wregglej - 149034 allowing the channel name and the directory name to vary independently. if not self.options.channel is None: #Get the list of channels with leading and trailing whitespace removed. channels = [ x.strip() for x in self.options.channel.split(',') if x ] #Get the list of directories to upload. At this point it's the list of arguments. dirs = self.args elif not self.args: #If we get to this point, then --channel wasn't used and nothing was included as arguments. #Assumes that the directories in topdir are the ones we want to upload, and since no channels were #specified that each directory is it's own channel. channels = os.listdir(topdir) dirs = None print("No config channels specified, using %s" % channels) else: #At this point, --channel wasn't used but there was something included as an argument. #The name of the channel is assumed to be the same as the name of the directory. channels = self.args dirs = None #If dirs isn't None, then each directory needs to be uploaded into each channel. if dirs: for channel in channels: for directory in dirs: self.upload_config_channel(topdir, channel, directory) #If dirs is None, then each channel is it's own channel. else: for channel in channels: self.upload_config_channel(topdir, channel, channel)
def get_raw_file_info(self, config_channel, repopath, revision=None): """ given a namepath, return the raw data passed by the server """ log_debug(5) params = { 'session': self.session, 'config_channel': config_channel, 'path': repopath, } if revision is not None: params['revision'] = revision try: result = self.rpc_call('config.management.get_file', params) except xmlrpclib.Fault, e: if e.faultCode == -4011: # File not present raise cfg_exceptions.RepositoryFileMissingError( config_channel, repopath), None, sys.exc_info()[2] raise
def get_raw_file_info(self, config_channel, repopath, revision=None): """ given a namepath, return the raw data passed by the server """ log_debug(5) params = { 'session' : self.session, 'config_channel' : config_channel, 'path' : repopath, } if revision is not None: params['revision'] = revision try: result = self.rpc_call('config.management.get_file', params) except xmlrpclib.Fault, e: if e.faultCode == -4011: # File not present raise cfg_exceptions.RepositoryFileMissingError(config_channel, repopath), None, sys.exc_info()[2] raise
def run(self): log_debug(2) r = self.repository if len(self.args) == 0: die(0, "No files supplied (use --help for help)") channel = self.options.channel if not channel: die(6, "Config channel not specified") r = self.repository if not r.config_channel_exists(channel): die(6, "Error: config channel %s does not exist" % channel) files = [utils.normalize_path(x) for x in self.args] files_to_remove = [] if self.options.topdir: if not os.path.isdir(self.options.topdir): die(8, "--topdir specified, but `%s' not a directory" % self.options.topdir) for f in files: if not f.startswith(self.options.topdir): die(8, "--topdir %s specified, but file `%s' doesn't comply" % (self.options.topdir, f)) files_to_remove.append((f, f[len(self.options.topdir):])) else: for f in files: files_to_remove.append((f, f)) print("Removing from config channel %s" % channel) for (local_file, remote_file) in files_to_remove: try: r.remove_file(channel, remote_file) except xmlrpclib.Fault: e = sys.exc_info()[1] if e.faultCode == -4011: print("%s does not exist" % remote_file) continue raise else: print("%s removed" % remote_file)
def run(self): log_debug(2) #5/12/05 wregglej - 149034 changed r into a instance variable self.r = self.repository topdir = self.options.topdir if not topdir: die(7, "--topdir not specified") if not os.path.isdir(topdir): die(8, "--topdir specified, but `%s' not a directory" % topdir) topdir = utils.normalize_path(topdir) #5/12/05 wregglej - 149034 allowing the channel name and the directory name to vary independently. if not self.options.channel is None: #Get the list of channels with leading and trailing whitespace removed. channels = map(string.strip, string.split(self.options.channel,',')) #Get the list of directories to upload. At this point it's the list of arguments. dirs = self.args elif not self.args: #If we get to this point, then --channel wasn't used and nothing was included as arguments. #Assumes that the directories in topdir are the ones we want to upload, and since no channels were #specified that each directory is it's own channel. channels = os.listdir(topdir) dirs = None print "No config channels specified, using %s" % channels else: #At this point, --channel wasn't used but there was something included as an argument. #The name of the channel is assumed to be the same as the name of the directory. channels = self.args dirs = None #If dirs isn't None, then each directory needs to be uploaded into each channel. if dirs: for channel in channels: for directory in dirs: self.upload_config_channel(topdir, channel, directory) #If dirs is None, then each channel is it's own channel. else: for channel in channels: self.upload_config_channel(topdir, channel, channel)
def get_file_revisions(self, config_channel, repopath): """ Fetch the file's revisions """ log_debug(4) params = { 'session': self.session, 'config_channel': config_channel, 'path': repopath, } try: revisions = self.rpc_call('config.management.list_file_revisions', params) except xmlrpclib.Fault, e: if e.faultCode == -4011: # File not present raise cfg_exceptions.RepositoryFileMissingError( config_channel, repopath), None, sys.exc_info()[2] raise
def get_file_revisions(self, config_channel, repopath): """ Fetch the file's revisions """ log_debug(4) params = { 'session' : self.session, 'config_channel' : config_channel, 'path' : repopath, } try: revisions = self.rpc_call('config.management.list_file_revisions', params) except repository.rpclib.Fault, e: if e.faultCode == -4011: # File not present raise cfg_exceptions.RepositoryFileMissingError( config_channel, repopath) raise e
def run(self): log_debug(2) r = self.repository channel = self.options.channel if not channel: die(6, "Config channel not specified") if not self.args: die(7, "No files specified") print("Analyzing files in config channel %s" % channel) for f in self.args: if not r.has_file(channel, f): die(8, "Config channel %s does not contain file %s" % (channel, f)) try: revisions = r.get_file_revisions(channel, f) except cfg_exceptions.RepositoryFileMissingError: print("%s: not in config channel" % f) continue print("%s: %s" % (f, " ".join([str(x) for x in revisions])))
def run(self): log_debug(2) r = self.repository if not self.args: die(6, "No config channels specified") topdir = self.options.topdir if not topdir: die(7, "--topdir not specified") if not os.path.isdir(topdir): die(8, "--topdir specified, but `%s' not a directory" % topdir) for ns in self.args: if not r.config_channel_exists(ns): die(6, "Error: config channel %s does not exist" % ns) deploy_files(utils.join_path(topdir, ns), r, r.list_files(ns), config_channel=ns)
def rollback(self): """revert the transaction""" log_debug(3, "rolling back") # restore old file from backup asap for path in self.backup_by_path.keys(): log_debug(6, "restoring %s from %s ..." % (path, self.backup_by_path[path])) # os.rename will fail if the backup file and the old file are on different partitions # need to make sure to handle it if we catch a 'OSError: [Errno 18] Invalid cross-device link' try: os.rename(self.backup_by_path[path], path) except OSError, e: if e.errno == 18: log_debug(9, "os.rename failed, using shutil.copy") shutil.copy(self.backup_by_path[path], path) else: raise log_debug(9, "%s restored" % path)
class ClientRepository(repository.RPC_Repository): default_systemid = "/etc/sysconfig/rhn/systemid" # bug #170825,169203: reusing the base class's default value for setup_network def __init__(self, setup_network=1): repository.RPC_Repository.__init__(self, setup_network) systemid_file = local_config.get("systemid") or self.default_systemid try: f = open(systemid_file, "r") except IOError, e: sys.stderr.write("Cannot open %s: %s\n" % (systemid_file, e)) sys.exit(1) self.system_id = f.read() f.close() log_debug(4, 'system id', self.system_id) self.files_to_delete = []