def upload_config_channel(self, topdir, channel, directory_name): if not self.r.config_channel_exists(channel): die(6, "Error: config channel %s does not exist" % channel) if self.options.disable_selinux: selinux_ctx = '' else: selinux_ctx = None print "Using config channel %s" % channel channel_dir = utils.join_path(topdir, directory_name) if not os.path.exists(channel_dir): die(6, "Error: channel directory %s does not exist" % channel_dir) flist = list_files_recursive(channel_dir) for (dirname, filenames) in flist: assert dirname.startswith(channel_dir) remote_dirname = dirname[len(channel_dir):] for f in filenames: local_file = utils.join_path(dirname, f) remote_file = utils.join_path(remote_dirname, f) print "Uploading %s from %s" % (remote_file, local_file) try: self.r.put_file(channel, remote_file, local_file, is_first_revision=0, selinux_ctx = selinux_ctx) except cfg_exceptions.RepositoryFilePushError, e: log_error(e)
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) 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) 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 if len(self.args): die(5, "No arguments required") print("Available config channels:") for ns in r.list_config_channels(): print(" %s" % ns)
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 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 authenticate(self, username=None, password=None): # entry point for repository authentication try: self.repository.login() except cfg_exceptions.InvalidSession: if not username : username=local_config.get('username') if not password : (username, password) = self.get_auth_info(username) try: self.repository.login(username=username, password=password) except cfg_exceptions.InvalidSession: e = sys.exc_info()[1] rhn_log.die(1, "Session error: %s\n" % e)
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 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) #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 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) 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 diff_file(self, channel, path, local_file, revision): r = self.repository try: info = r.get_raw_file_info(channel, path, revision) if info.has_key('encoding') and info['file_contents']: if info['encoding'] == 'base64': info['file_contents'] = base64.decodestring(info['file_contents']) else: die(9, 'Error: unknown encoding %s' % info['encoding']) except cfg_exceptions.RepositoryFileMissingError: die(2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info['filetype'] != 'symlink' : die(8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file) if info['filetype'] == 'symlink' and not os.path.islink(local_file) : die(8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file) if info['filetype'] == 'symlink': src_link = info['symlink'] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % (path,src_link, path, dest_link) return "" fromlines = info['file_contents'].splitlines(1) tolines = open(local_file, 'r').readlines() diff_output = difflib.unified_diff(fromlines, tolines, info['path'], local_file) first_row = second_row = '' try: first_row = diff_output.next() second_row = diff_output.next() except StopIteration: pass file_stat = os.lstat(local_file) local_info = r.make_stat_info(local_file, file_stat) # rhel4 do not support selinux if not 'selinux_ctx' in local_info: local_info['selinux_ctx'] = '' if 'selinux_ctx' not in info: info['selinux_ctx'] = '' if not first_row and not self.__attributes_differ(info, local_info): return "" else: template = "--- %s\t%s\tattributes: %s %s %s %s\tconfig channel: %s\trevision: %s" if not info.has_key('modified'): info['modified'] = '' first_row = template % (path, str(info['modified']), ostr_to_sym(info['filemode'], info['filetype']), info['username'], info['groupname'], info['selinux_ctx'], channel, info['revision'], ) second_row = template % (local_file, f_date(datetime.fromtimestamp(local_info['mtime'])), ostr_to_sym(local_info['mode'], 'file'), local_info['user'], local_info['group'], local_info['selinux_ctx'], 'local file', None ) return first_row + '\n' + second_row + '\n' + ''.join(list(diff_output))
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([len(s[0]) for s in 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(bstr(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) 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 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 diff_file(self, channel, path, local_file, revision): r = self.repository try: #5/11/05 wregglej - 157066 dirs_created is returned by get_file_info, now. temp_file, info, dirs_created = r.get_file_info(channel, path, revision=revision) except cfg_exceptions.RepositoryFileMissingError: die(2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info['filetype'] != 'symlink' : die(8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file) if info['filetype'] == 'symlink' and not os.path.islink(local_file) : die(8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file) if info['filetype'] == 'symlink': src_link = info['symlink'] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % (path,src_link, path, dest_link) return "" # Test -u option to diff diffcmd = "/usr/bin/diff -u" pipe = os.popen("%s %s %s 2>/dev/null" % (diffcmd, temp_file, local_file)) pipe.read() # Read the output so GNU diff is happy ret = pipe.close() if ret == None: ret = 0 ret = ret/256 # Return code in upper byte if ret == 2: # error in diff call diffcmd = "/usr/bin/diff -c" pipe = os.popen("%s %s %s" % (diffcmd, temp_file, local_file)) first_row = pipe.readline() if not first_row: return "" elif utils.startswith(first_row, "---"): first_row = "--- %s\tconfig_channel: %s\trevision: %s\n" % ( path, channel, info['revision'] ) elif utils.startswith(first_row, "***"): # This happens when we drop back to "diff -c" first_row = "*** %s\tconfig_channel: %s\trevision: %s\n" % ( path, channel, info['revision'] ) return first_row + pipe.read()
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 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) 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 diff_file(self, channel, path, local_file, revision): r = self.repository try: info = r.get_raw_file_info(channel, path, revision) if 'encoding' in info and info['file_contents']: if info['encoding'] == 'base64': info['file_contents'] = base64.decodestring(bstr(info['file_contents'])) else: die(9, 'Error: unknown encoding %s' % info['encoding']) except cfg_exceptions.RepositoryFileMissingError: die(2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info['filetype'] != 'symlink' : die(8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file) if info['filetype'] == 'symlink' and not os.path.islink(local_file) : die(8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file) if info['filetype'] == 'symlink': src_link = info['symlink'] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % (path,src_link, path, dest_link) return "" response_output = "" content_differs = False if 'is_binary' in info and info['is_binary'] == 'Y': from_content = info['file_contents'] to_file = open(local_file, 'rb') to_content = to_file.read() to_file.close() if len(from_content) != len(to_content): content_differs = True else: for i in range(len(from_content)): if from_content[i] != to_content[i]: content_differs = True break if content_differs: response_output = "Binary file content differs\n" else: fromlines = sstr(info['file_contents']).splitlines(1) tofile = open(local_file, 'r') tolines = tofile.readlines() tofile.close() diff_output = difflib.unified_diff(fromlines, tolines, info['path'], local_file) first_row = second_row = '' try: first_row = next(diff_output) # if content was same, exception thrown so following # lines don't execute content_differs = True second_row = next(diff_output) response_output = ''.join(list(diff_output)) except StopIteration: pass file_stat = os.lstat(local_file) local_info = r.make_stat_info(local_file, file_stat) # rhel4 do not support selinux if not 'selinux_ctx' in local_info: local_info['selinux_ctx'] = '' if 'selinux_ctx' not in info: info['selinux_ctx'] = '' if not content_differs and not self.__attributes_differ(info, local_info): return "" else: template = "%s %s\t%s\tattributes: %s %s %s %s\tconfig channel: %s\trevision: %s" if 'modified' not in info: info['modified'] = '' first_row = template % ('---', path, str(info['modified']), ostr_to_sym(info['filemode'], info['filetype']), info['username'], info['groupname'], info['selinux_ctx'], channel, info['revision'], ) second_row = template % ('+++', local_file, f_date(datetime.fromtimestamp(local_info['mtime'])), ostr_to_sym(local_info['mode'], 'file'), local_info['user'], local_info['group'], local_info['selinux_ctx'], 'local file', None ) return first_row + '\n' + second_row + '\n' + response_output
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 diff_file(self, channel, path, local_file, revision): r = self.repository try: info = r.get_raw_file_info(channel, path, revision) if info.has_key("encoding") and info["file_contents"]: if info["encoding"] == "base64": info["file_contents"] = base64.decodestring(info["file_contents"]) else: die(9, "Error: unknown encoding %s" % info["encoding"]) except cfg_exceptions.RepositoryFileMissingError: die(2, "Error: no such file %s (revision %s) in config channel %s" % (path, revision, channel)) if os.path.islink(local_file) and info["filetype"] != "symlink": die( 8, "Cannot diff %s; the file on the system is a symbolic link while the file in the channel is not. " % local_file, ) if info["filetype"] == "symlink" and not os.path.islink(local_file): die( 8, "Cannot diff %s; the file on the system is not a symbolic link while the file in the channel is. " % local_file, ) if info["filetype"] == "symlink": src_link = info["symlink"] dest_link = os.readlink(local_file) if src_link != os.readlink(local_file): return "Symbolic links differ. Channel: '%s' -> '%s' System: '%s' -> '%s' \n " % ( path, src_link, path, dest_link, ) return "" fromlines = info["file_contents"].splitlines(1) tolines = open(local_file, "r").readlines() diff_output = difflib.unified_diff(fromlines, tolines, info["path"], local_file) first_row = second_row = "" try: first_row = diff_output.next() second_row = diff_output.next() except StopIteration: pass file_stat = os.lstat(local_file) local_info = r.make_stat_info(local_file, file_stat) # rhel4 do not support selinux if not "selinux_ctx" in local_info: local_info["selinux_ctx"] = "" if "selinux_ctx" not in info: info["selinux_ctx"] = "" if not first_row and not self.__attributes_differ(info, local_info): return "" else: template = "--- %s\t%s\tattributes: %s %s %s %s\tconfig channel: %s\trevision: %s" if not info.has_key("modified"): info["modified"] = "" first_row = template % ( path, str(info["modified"]), ostr_to_sym(info["filemode"], info["filetype"]), info["username"], info["groupname"], info["selinux_ctx"], channel, info["revision"], ) second_row = template % ( local_file, f_date(datetime.fromtimestamp(local_info["mtime"])), ostr_to_sym(local_info["mode"], "file"), local_info["user"], local_info["group"], local_info["selinux_ctx"], "local file", None, ) return first_row + "\n" + second_row + "\n" + "".join(list(diff_output))
def run(self): log_debug(2) r = self.repository channel = self.options.channel if not channel: die(6, "Config channel not specified") topdir = self.options.topdir if topdir: if not os.path.isdir(self.options.topdir): die(8, "--topdir specified, but `%s' not a directory" % self.options.topdir) if not self.args: die(7, "No files specified") revision = self.options.revision if revision: if len(self.args) > 1: die(9, "--revision specified with multiple files") dep_trans = None if topdir: dep_trans = DeployTransaction(transaction_root=topdir) dep_trans.deploy_callback(deploying_mesg_callback) for f in self.args: try: directory = topdir or tempfile.gettempdir() # 5/11/05 wregglej - 157066 dirs_created is returned from get_file_info. (temp_file, info, dirs_created) = r.get_file_info( channel, f, revision=revision, auto_delete=0, dest_directory=directory ) except cfg_exceptions.RepositoryFileMissingError: if revision is not None: die(2, "Error: file %s (revision %s) not in config " "channel %s" % (f, revision, channel)) else: die(2, "Error: file %s not in config channel %s" % (f, channel)) if topdir: # 5/11/05 wregglej - 157066 dirs_created now gets passed into add_preprocessed. dep_trans.add_preprocessed(f, temp_file, info, dirs_created, strict_ownership=0) continue elif info.get("filetype") == "symlink": print "%s -> %s" % (info["path"], info["symlink"]) continue elif info.get("filetype") == "directory": print "%s is a directory entry, nothing to get" % info["path"] continue else: print open(temp_file).read() os.unlink(temp_file) if topdir: try: dep_trans.deploy() except Exception, e: try: dep_trans.rollback() except FailedRollback, e2: raise e2, "FAILED ROLLBACK: ", sys.exc_info()[2] # 5/3/05 wregglej - 136415 Added exception stuff for missing user info. except cfg_exceptions.UserNotFound, f: raise
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: die(2, e[0])
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) files = map(utils.normalize_path, self.args) files_to_push = [] if self.options.dest_file: if len(files) != 1: die(7, "--dest-file accepts a single file") if not (self.options.dest_file[0] == os.sep): die(7, "--dest-file argument must begin with " + os.sep) files_to_push.append((files[0], self.options.dest_file)) elif self.options.topdir: if not os.path.isdir(self.options.topdir): die(8, "--topdir specified, but `%s' not a directory" % self.options.topdir) #5/11/05 wregglej - 141790 remove the trailing slash from topdir self.options.topdir = utils.rm_trailing_slash(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_push.append((f, f[len(self.options.topdir):])) else: for f in files: #if a file is given w/o a full path, then use the abspath of the #file as name of the file to be uploaded into the channel if not (f[0] == os.sep): files_to_push.append((f, os.path.abspath(f))) else: files_to_push.append((f, f)) for (local_file, remote_file) in files_to_push: if not os.path.exists(local_file): if self.options.ignore_missing: files_to_push.remove((local_file,remote_file)) print "Local file %s does not exist. Ignoring file..." %(local_file) else: die(9, "No such file `%s'" % local_file) print "Pushing to channel %s:" % (channel, ) delim_start = self.options.delim_start delim_end = self.options.delim_end selinux_ctx = None if type(self.options.selinux_context) != None: selinux_ctx = self.options.selinux_context for (local_file, remote_file) in files_to_push: try: r.put_file(channel, remote_file, local_file, is_first_revision=self.is_first_revision, delim_start=delim_start, delim_end=delim_end, selinux_ctx=selinux_ctx) except cfg_exceptions.RepositoryFileExistsError, e: log_error("Error: %s is already in channel %s" % (remote_file, channel)) except cfg_exceptions.RepositoryFilePushError, e: log_error("Error pushing file: %s" % e)
class Handler(handler_base.HandlerBase): _usage_options = "[options] file" _options_table = [ handler_base.HandlerBase._option_class( '-c', '--channel', action="append", help="Use this config channel", ), handler_base.HandlerBase._option_class( '-r', '--revision', action="append", help="Use this revision", ), ] 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: die(2, e[0]) except cfg_exceptions.BinaryFileDiffError, e: die(3, e[0])
def run(self): log_debug(2) r = self.repository channel = self.options.channel if not channel: die(6, "Config channel not specified") topdir = self.options.topdir if topdir: if not os.path.isdir(self.options.topdir): die( 8, "--topdir specified, but `%s' not a directory" % self.options.topdir) if not self.args: die(7, "No files specified") revision = self.options.revision if revision: if len(self.args) > 1: die(9, "--revision specified with multiple files") dep_trans = None if topdir: dep_trans = DeployTransaction(transaction_root=topdir) dep_trans.deploy_callback(deploying_mesg_callback) for f in self.args: try: directory = topdir or tempfile.gettempdir() #5/11/05 wregglej - 157066 dirs_created is returned from get_file_info. (temp_file, info, dirs_created) = r.get_file_info(channel, f, revision=revision, auto_delete=0, dest_directory=directory) except cfg_exceptions.RepositoryFileMissingError: if revision is not None: die( 2, "Error: file %s (revision %s) not in config " "channel %s" % (f, revision, channel)) else: die( 2, "Error: file %s not in config channel %s" % (f, channel)) if topdir: #5/11/05 wregglej - 157066 dirs_created now gets passed into add_preprocessed. dep_trans.add_preprocessed(f, temp_file, info, dirs_created, strict_ownership=0) continue elif info.get('filetype') == 'symlink': print("%s -> %s" % (info['path'], info['symlink'])) continue elif info.get('filetype') == 'directory': print("%s is a directory entry, nothing to get" % info['path']) continue else: print(open(temp_file).read()) os.unlink(temp_file) if topdir: try: dep_trans.deploy() except Exception: try: dep_trans.rollback() except FailedRollback: raise_with_tb(FailedRollback("FAILED ROLLBACK: "), sys.exc_info()[2]) #5/3/05 wregglej - 136415 Added exception stuff for missing user info. except cfg_exceptions.UserNotFound: raise #5/5/05 wregglej - 136415 Added exception handling for unknown group. except cfg_exceptions.GroupNotFound: raise else: raise_with_tb( Exception("Deploy failed, rollback successful: "), sys.exc_info()[2])
def main(self): args = [] show_help = None debug_level = 3 mode = None dict_name_opt = { '--server-name': None, '--password': None, '--username': None, '--config': None, } for index in range(1, len(sys.argv)): arg = sys.argv[index] param = [x for x in dict_name_opt.items() if x[1] == 0] if param: if arg.startswith('-') or arg in self.modes: # not perfect, but at least a little bit better print("Option %s requires an argument" % dict_name_opt[param[0][0]]) return 1 dict_name_opt[param[0][0]] = arg continue if arg in ('--help', '-h'): show_help = 1 continue param = [s for s in dict_name_opt.keys() if arg.startswith(s)] if param: rarg = arg[len(param[0]):] if not rarg: dict_name_opt[param[0]] = 0 if index == len(sys.argv) - 1: print("Option %s requires an argument" % param[0]) return 1 continue if rarg[0] == '=': if len(rarg) == 1: print("Option %s requires an argument" % param[0]) return 1 dict_name_opt[param[0]] = rarg[1:] continue print("Unknown option %s" % arg) return 1 if mode is None: # This should be the mode mode = arg if mode == '': # Bad self.usage(1) if mode[0] == '-': # Mode can't be an option self.usage(1) if mode not in self.modes: print("Unknown mode %s" % mode) self.usage(1) continue args.append(arg) server_name = dict_name_opt['--server-name'] password = dict_name_opt['--password'] username = dict_name_opt['--username'] config_file_override = dict_name_opt['--config'] if config_file_override and not os.path.isfile(config_file_override): rhn_log.die(1, "Config file %s does not exist.", config_file_override) rhn_log.set_debug_level(debug_level) if mode is None: # No args were specified self.usage(0) execname = os.path.basename(sys.argv[0]) # Class names cannot have dot in them, so strip the extension execname = execname.split('.', 1)[0] mode_module = mode.replace('-', '_') module_name = "%s_%s" % (self.mode_prefix, mode_module) full_module_name = "%s.%s" % (self.plugins_dir, module_name) try: module = __import__(full_module_name) except ImportError: e = sys.exc_info()[1] rhn_log.die(1, "Unable to load plugin for mode '%s': %s" % (mode, e)) module = getattr(module, module_name) if show_help: # Display the per-module help handler = module.Handler(args, None, mode=mode, exec_name=execname) handler.usage() return 0 cfg = config.initUp2dateConfig() up2date_cfg = dict(cfg.items()) if server_name: local_config.init(self.config_section, defaults=up2date_cfg, config_file_override=config_file_override, server_url="https://" + server_name) else: local_config.init(self.config_section, defaults=up2date_cfg, config_file_override=config_file_override) try: server_name = local_config.get('server_url') except InterpolationError: e = sys.exc_info()[1] if e.option == 'server_url': server_name = config.getServerlURL() up2date_cfg['proto'] = urlsplit(server_name[0])[0] if up2date_cfg['proto'] == '': up2date_cfg['proto'] = 'https' up2date_cfg['server_list'] = [ urlsplit(x)[2] for x in server_name ] else: up2date_cfg['server_list'] = [ urlsplit(x)[1] for x in server_name ] server_name = (up2date_cfg['server_list'])[0] local_config.init( self.config_section, defaults=up2date_cfg, config_file_override=config_file_override, server_name=server_name) print("Using server name %s" % server_name) # set the debug level through the config rhn_log.set_debug_level(int(local_config.get('debug_level') or 0)) rhn_log.set_logfile(local_config.get('logfile') or "/var/log/rhncfg") # Multi-level import - __import__("foo.bar") does not return the bar # module, but the foo module with bar loaded # XXX Error checking repo_class = local_config.get('repository_type') if repo_class is None: rhn_log.die( 1, "repository_type not set (missing configuration file?)") repo_module_name = "%s.%s" % (self.plugins_dir, repo_class) try: repo_module = __import__(repo_module_name) except ImportError: e = sys.exc_info()[1] rhn_log.die(1, "Unable to load repository module: %s" % e) try: repo_module = getattr(repo_module, repo_class) except AttributeError: rhn_log.die(1, "Malformed repository module") try: repo = getattr(repo_module, self.repository_class_name)() except AttributeError: rhn_log.die(1, "Missing repository class") except InterpolationError: e = sys.exc_info()[1] if e.option == 'server_url': #pkilambi: bug#179367# backtic is replaced with single quote rhn_log.die( 1, "Missing 'server_url' configuration variable; please refer to the config file" ) raise except cfg_exceptions.ConfigurationError: e = sys.exc_info()[1] rhn_log.die(e) except gaierror: e = sys.exc_info()[1] print("Socket Error: %s" % (e.args[1], )) sys.exit(1) handler = module.Handler(args, repo, mode=mode, exec_name=execname) try: try: handler.authenticate(username, password) handler.run() except cfg_exceptions.AuthenticationError: e = sys.exc_info()[1] rhn_log.die(1, "Authentication failed: %s" % e) except Exception: raise finally: repo.cleanup() return 0
def main(self): args = [] show_help = None debug_level = 3 mode = None dict_name_opt={'--server-name': None,'--password': None,'--username': None,} for index in range(1,len(sys.argv)): arg=sys.argv[index] param = [x for x in dict_name_opt.items() if x[1] == 0] if param: if arg.startswith('-') or arg in self.modes: # not perfect, but at least a little bit better print("Option %s requires an argument" % dict_name_opt[param[0][0]]) return 1 dict_name_opt[param[0][0]] = arg continue if arg in ('--help', '-h'): show_help = 1 continue param = [s for s in dict_name_opt.keys() if arg.startswith(s)] if param: rarg = arg[len(param[0]):] if not rarg: dict_name_opt[param[0]] = 0 if index == len(sys.argv) - 1: print("Option %s requires an argument" % param[0]) return 1 continue if rarg[0] == '=': if len(rarg) == 1: print("Option %s requires an argument" % param[0]) return 1 dict_name_opt[param[0]] = rarg[1:] continue print("Unknown option %s" % arg) return 1 if mode is None: # This should be the mode mode = arg if mode == '': # Bad self.usage(1) if mode[0] == '-': # Mode can't be an option self.usage(1) if mode not in self.modes: print("Unknown mode %s" % mode) self.usage(1) continue args.append(arg) server_name = dict_name_opt['--server-name'] password = dict_name_opt['--password'] username = dict_name_opt['--username'] rhn_log.set_debug_level(debug_level) if mode is None: # No args were specified self.usage(0) execname = os.path.basename(sys.argv[0]) # Class names cannot have dot in them, so strip the extension execname = execname.split('.', 1)[0] mode_module = mode.replace('-', '_') module_name = "%s_%s" % (self.mode_prefix, mode_module) full_module_name = "%s.%s" % (self.plugins_dir, module_name) try: module = __import__(full_module_name) except ImportError: e = sys.exc_info()[1] rhn_log.die(1, "Unable to load plugin for mode '%s': %s" % (mode, e)) module = getattr(module, module_name) if show_help: # Display the per-module help handler = module.Handler(args, None, mode=mode, exec_name=execname) handler.usage() return 0 cfg = config.initUp2dateConfig() up2date_cfg = dict(cfg.items()) if server_name: local_config.init(self.config_section, defaults=up2date_cfg, server_url="https://" + server_name) else: local_config.init(self.config_section, defaults=up2date_cfg) try: server_name = local_config.get('server_url') except InterpolationError: e = sys.exc_info()[1] if e.option == 'server_url': server_name = config.getServerlURL() up2date_cfg['proto'] = urlsplit(server_name[0])[0] if up2date_cfg['proto'] == '': up2date_cfg['proto'] = 'https' up2date_cfg['server_list'] = [urlsplit(x)[2] for x in server_name] else: up2date_cfg['server_list'] = [urlsplit(x)[1] for x in server_name] server_name = (up2date_cfg['server_list'])[0] local_config.init(self.config_section, defaults=up2date_cfg, server_name=server_name) print("Using server name %s" % server_name) # set the debug level through the config rhn_log.set_debug_level(int(local_config.get('debug_level') or 0)) rhn_log.set_logfile(local_config.get('logfile') or "/var/log/rhncfg") # Multi-level import - __import__("foo.bar") does not return the bar # module, but the foo module with bar loaded # XXX Error checking repo_class = local_config.get('repository_type') if repo_class is None: rhn_log.die(1, "repository_type not set (missing configuration file?)") repo_module_name = "%s.%s" % (self.plugins_dir, repo_class) try: repo_module = __import__(repo_module_name) except ImportError: e = sys.exc_info()[1] rhn_log.die(1, "Unable to load repository module: %s" % e) try: repo_module = getattr(repo_module, repo_class) except AttributeError: rhn_log.die(1, "Malformed repository module") try: repo = getattr(repo_module, self.repository_class_name)() except AttributeError: rhn_log.die(1, "Missing repository class") except InterpolationError: e = sys.exc_info()[1] if e.option == 'server_url': #pkilambi: bug#179367# backtic is replaced with single quote rhn_log.die(1, "Missing 'server_url' configuration variable; please refer to the config file") raise except cfg_exceptions.ConfigurationError: e = sys.exc_info()[1] rhn_log.die(e) except gaierror: e = sys.exc_info()[1] print("Socket Error: %s" % (e.args[1],)) sys.exit(1) handler = module.Handler(args, repo, mode=mode, exec_name=execname) try: try: handler.authenticate(username, password) handler.run() except cfg_exceptions.AuthenticationError: e = sys.exc_info()[1] rhn_log.die(1, "Authentication failed: %s" % e) except Exception: raise finally: repo.cleanup() return 0