rel-eng/packages/spacecmd | 2
spacecmd/spacecmd.spec | 21 +++
spacecmd/src/bin/spacecmd | 6
spacecmd/src/lib/configchannel.py | 217 +++++++++++++++++++++++-------------
spacecmd/src/lib/misc.py | 6
spacecmd/src/lib/report.py | 28 ++--
spacecmd/src/lib/softwarechannel.py | 199 +++++++++++++++++++++++----------
7 files changed, 327 insertions(+), 152 deletions(-)
New commits:
commit 1d031d8166ab5c17d1481b7d23911d03126aae41
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 14:08:45 2010 -0400
Automatic commit of package [spacecmd] release [0.6.1-1].
diff --git a/rel-eng/packages/spacecmd b/rel-eng/packages/spacecmd
index 11d4954..7d89031 100644
--- a/rel-eng/packages/spacecmd
+++ b/rel-eng/packages/spacecmd
@@ -1 +1 @@
-0.5.7-1 spacecmd/
+0.6.1-1 spacecmd/
diff --git a/spacecmd/spacecmd.spec b/spacecmd/spacecmd.spec
index 90712d9..4b6362a 100644
--- a/spacecmd/spacecmd.spec
+++ b/spacecmd/spacecmd.spec
@@ -4,7 +4,7 @@
%endif
Name: spacecmd
-Version: 0.5.7
+Version: 0.6.1
Release: 1%{?dist}
Summary: Command-line interface to Spacewalk and Satellite servers
@@ -57,6 +57,25 @@ touch %{buildroot}/%{python_sitelib}/spacecmd/__init__.py
%doc %{_mandir}/man1/spacecmd.1.gz
%changelog
+* Mon Sep 20 2010 Aron Parsons <aparsons(a)redhat.com> 0.6.1-1
+- support symlinks, selinux contexts and revisions in configchannel_*
+ (aparsons(a)redhat.com)
+- added new function softwarechannel_listallpackages
+ (aparsons(a)redhat.com)
+- avoid proxy timeouts when cloning errata by doing them individually
+ (aparsons(a)redhat.com)
+- allow --debug to be passed multiple times (aparsons(a)redhat.com)
+- revert to the old-style of errata merging due to bugzilla 591291
+ (aparsons(a)redhat.com)
+- cleanup column headers in report_outofdatesystems
+ (aparsons(a)redhat.com)
+- show the last checkin time in report_inactivesystems
+ (aparsons(a)redhat.com)
+- clarify what 'Original State' means when cloning a software channel
+ (aparsons(a)redhat.com)
+- remove prompts for summary/description when creating software
+ channels and just use the name (aparsons(a)redhat.com)
+
* Fri Aug 20 2010 Aron Parsons <aparsons(a)redhat.com> 0.5.7-1
- simplify checks for debug mode (aparsons(a)redhat.com)
- enable verbose mode for xmlrpclib when debugging is enabled
commit 74084dd382d12205573a8a893def8748ac44fe41
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 14:07:12 2010 -0400
spacecmd: support symlinks, selinux contexts and revisions in configchannel_*
diff --git a/spacecmd/src/lib/configchannel.py b/spacecmd/src/lib/configchannel.py
index 600ea8d..5cf224d 100644
--- a/spacecmd/src/lib/configchannel.py
+++ b/spacecmd/src/lib/configchannel.py
@@ -99,7 +99,7 @@ def do_configchannel_listfiles(self, args, doreturn=False):
def help_configchannel_filedetails(self):
print 'configchannel_filedetails: Show the details of a file'
print 'in a configuration channel'
- print 'usage: configchannel_filedetails CHANNEL <FILE ...>'
+ print 'usage: configchannel_filedetails CHANNEL FILE [REVISION]'
def complete_configchannel_filedetails(self, text, line, beg, end):
parts = line.split(' ')
@@ -120,47 +120,60 @@ def do_configchannel_filedetails(self, args):
self.help_configchannel_filedetails()
return
- add_separator = False
-
channel = args[0]
- filenames = args[1:]
+ filename = args[1]
+ revision = None
+
+ try:
+ revision = int(args[2])
+ except:
+ pass
# the server return a null exception if an invalid file is passed
valid_files = self.do_configchannel_listfiles(channel, True)
- for f in filenames:
- if not f in valid_files:
- filenames.remove(f)
- logging.warning('%s is not in this configuration channel' % f)
- continue
+ if not filename in valid_files:
+ logging.warning('%s is not in this configuration channel' % filename)
+ return
- files = self.client.configchannel.lookupFileInfo(self.session,
- channel,
- filenames)
+ if revision:
+ details = self.client.configchannel.lookupFileInfo(self.session,
+ channel,
+ filename,
+ revision)
+ else:
+ results = self.client.configchannel.lookupFileInfo(self.session,
+ channel,
+ [ filename ])
- for f in files:
- if add_separator: print self.SEPARATOR
- add_separator = True
+ # grab the first item since we only do one file
+ details = results[0]
- print 'File: %s' % f.get('path')
- print 'Type: %s' % f.get('type')
- print 'Revision: %i' % f.get('revision')
- print 'Created: %s' % f.get('creation')
- print 'Modified: %s' % f.get('modified')
+ print 'File: %s' % details.get('path')
+ print 'Type: %s' % details.get('type')
+ print 'Revision: %i' % details.get('revision')
+ print 'Created: %s' % details.get('creation')
+ print 'Modified: %s' % details.get('modified')
+ if details.get('type') == 'symlink':
+ print
+ print 'Target Path: %s' % details.get('target_path')
+ else:
print
- print 'Owner: %s' % f.get('owner')
- print 'Group: %s' % f.get('group')
- print 'Mode: %s' % f.get('permissions_mode')
+ print 'Owner: %s' % details.get('owner')
+ print 'Group: %s' % details.get('group')
+ print 'Mode: %s' % details.get('permissions_mode')
+
+ print 'SELinux Context: %s' % details.get('selinux_ctx')
- if f.get('type') == 'file':
- print 'MD5: %s' % f.get('md5')
- print 'Binary: %s' % f.get('binary')
+ if details.get('type') == 'file':
+ print 'MD5: %s' % details.get('md5')
+ print 'Binary: %s' % details.get('binary')
- if not f.get('binary'):
- print
- print 'Contents'
- print '--------'
- print f.get('contents')
+ if not details.get('binary'):
+ print
+ print 'Contents'
+ print '--------'
+ print details.get('contents')
####################
@@ -269,11 +282,14 @@ def do_configchannel_addfile(self, args, path=''):
channel = args[0]
- # defaults
+ # defaults
owner = 'root'
group = 'root'
mode = '644'
contents = ''
+ target_path = ''
+ selinux_ctx = ''
+ symlink = False
while path == '':
path = prompt_user('Path:')
@@ -294,57 +310,104 @@ def do_configchannel_addfile(self, args, path=''):
group = info.get('group')
mode = info.get('permissions_mode')
contents = info.get('contents')
+ target_path = info.get('target_path')
+ selinux_ctx = info.get('selinux_ctx')
- userinput = prompt_user('Directory [y/N]:')
- if re.match('y', userinput, re.I):
- directory = True
- else:
- directory = False
+ if info.get('type') == 'symlink':
+ symlink = True
+
+ # if this is a new file, ask if it's a symlink
+ if not symlink:
+ userinput = prompt_user('Symlink [y/N]:')
+ if re.match('y', userinput, re.I):
+ symlink = True
+ else:
+ symlink = False
+
+ if symlink:
+ target_input = prompt_user('Target Path [%s]:' % target_path)
+ selinux_input = prompt_user('SELinux Context [%s]:' % selinux_ctx)
- owner_input = prompt_user('Owner [%s]:' % owner)
- group_input = prompt_user('Group [%s]:' % group)
- mode_input = prompt_user('Permissions [%s]:' % mode)
-
- if owner_input:
- owner = owner_input
+ if target_input:
+ target_path = target_input
- if group_input:
- group = group_input
+ if selinux_input:
+ selinux_ctx = selinux_input
- if mode_input:
- mode = mode_input
+ file_info = { 'target_path' : target_path,
+ 'selinux_ctx' : selinux_ctx }
- if not directory:
- if contents:
- template = contents
+ print 'File: %s' % path
+ print 'Target Path: %s' % target_path
+ print 'SELinux Context: %s' % selinux_ctx
+ else:
+ userinput = prompt_user('Directory [y/N]:')
+ if re.match('y', userinput, re.I):
+ directory = True
else:
- template = ''
+ directory = False
- contents = editor(template = template, delete = True)
+ owner_input = prompt_user('Owner [%s]:' % owner)
+ group_input = prompt_user('Group [%s]:' % group)
+ mode_input = prompt_user('Permissions [%s]:' % mode)
+ selinux_input = prompt_user('SELinux Context [%s]:' % selinux_ctx)
- file_info = { 'contents' : ''.join(contents),
- 'owner' : owner,
- 'group' : group,
- 'permissions' : mode }
+ if owner_input:
+ owner = owner_input
- print 'File: %s' % path
- print 'Directory: %s' % directory
- print 'Owner: %s' % file_info['owner']
- print 'Group: %s' % file_info['group']
- print 'Mode: %s' % file_info['permissions']
+ if group_input:
+ group = group_input
- if not directory:
- print
- print 'Contents'
- print '--------'
- print file_info['contents']
+ if mode_input:
+ mode = mode_input
+
+ if selinux_input:
+ selinux_ctx = selinux_input
+
+ if not directory:
+ if contents:
+ template = contents
+ else:
+ template = ''
+
+ contents = editor(template = template, delete = True)
+
+ file_info = { 'contents' : ''.join(contents),
+ 'owner' : owner,
+ 'group' : group,
+ 'selinux_ctx' : selinux_ctx,
+ 'permissions' : mode }
+
+ print 'File: %s' % path
+ print 'Directory: %s' % directory
+ print 'Owner: %s' % file_info['owner']
+ print 'Group: %s' % file_info['group']
+ print 'Mode: %s' % file_info['permissions']
+ print 'SELinux Context: %s' % selinux_ctx
+
+ if not directory:
+ print
+ print 'Contents'
+ print '--------'
+ print file_info['contents']
+
+ # selinux_ctx can't be None
+ if not file_info['selinux_ctx']:
+ file_info['selinux_ctx'] = ''
if self.user_confirm():
- self.client.configchannel.createOrUpdatePath(self.session,
- channel,
- path,
- directory,
- file_info)
+ if symlink:
+ print file_info
+ self.client.configchannel.createOrUpdateSymlink(self.session,
+ channel,
+ path,
+ file_info)
+ else:
+ self.client.configchannel.createOrUpdatePath(self.session,
+ channel,
+ path,
+ directory,
+ file_info)
####################
@@ -356,17 +419,17 @@ def complete_configchannel_updatefile(self, text, line, beg, end):
parts = line.split(' ')
if len(parts) == 2:
- return tab_completer(self.do_configchannel_list('', True),
+ return tab_completer(self.do_configchannel_list('', True),
text)
elif len(parts) > 2:
channel = parts[1]
return tab_completer(self.do_configchannel_listfiles(channel,
- True),
+ True),
text)
def do_configchannel_updatefile(self, args):
args = parse_arguments(args)
-
+
if len(args) != 2:
self.help_configchannel_updatefile()
return
@@ -383,17 +446,17 @@ def complete_configchannel_removefiles(self, text, line, beg, end):
parts = line.split(' ')
if len(parts) == 2:
- return tab_completer(self.do_configchannel_list('', True),
+ return tab_completer(self.do_configchannel_list('', True),
text)
elif len(parts) > 2:
channel = parts[1]
return tab_completer(self.do_configchannel_listfiles(channel,
- True),
+ True),
text)
def do_configchannel_removefiles(self, args):
args = parse_arguments(args)
-
+
if len(args) < 2:
self.help_configchannel_removefiles()
return
commit 439fcb1ca234c90d278b2d9bcb814bcd647654dd
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 12:51:43 2010 -0400
spacecmd: added new function softwarechannel_listallpackages
diff --git a/spacecmd/src/lib/softwarechannel.py b/spacecmd/src/lib/softwarechannel.py
index 361ac2f..dfaa035 100644
--- a/spacecmd/src/lib/softwarechannel.py
+++ b/spacecmd/src/lib/softwarechannel.py
@@ -156,6 +156,39 @@ def do_softwarechannel_listpackages(self, args, doreturn=False):
####################
+def help_softwarechannel_listallpackages(self):
+ print 'softwarechannel_listallpackages: List all packages in a channel'
+ print 'usage: softwarechannel_listallpackages CHANNEL'
+
+def complete_softwarechannel_listallpackages(self, text, line, beg, end):
+ if len(line.split(' ')) == 2:
+ return tab_completer(self.do_softwarechannel_list('', True),
+ text)
+ else:
+ return []
+
+def do_softwarechannel_listallpackages(self, args, doreturn=False):
+ args = parse_arguments(args)
+
+ if not len(args):
+ self.help_softwarechannel_listallpackages()
+ return
+
+ channel = args[0]
+
+ packages = self.client.channel.software.listAllPackages(self.session,
+ channel)
+
+ packages = build_package_names(packages)
+
+ if doreturn:
+ return packages
+ else:
+ if len(packages):
+ print '\n'.join(sorted(packages))
+
+####################
+
def help_softwarechannel_details(self):
print 'softwarechannel_details: Show the details of a software channel'
print 'usage: softwarechannel_details <CHANNEL ...>'
commit 4242977a20741ca3c6bcaaee49d0572d468df80e
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 12:47:54 2010 -0400
spacecmd: avoid proxy timeouts when cloning errata by doing them individually
diff --git a/spacecmd/src/lib/softwarechannel.py b/spacecmd/src/lib/softwarechannel.py
index b3caa1e..361ac2f 100644
--- a/spacecmd/src/lib/softwarechannel.py
+++ b/spacecmd/src/lib/softwarechannel.py
@@ -595,6 +595,12 @@ def do_softwarechannel_adderrata(self, args):
errata = filter_results([ e.get('advisory_name') for e in source_errata ],
errata_wanted)
+ # keep the details for our matching errata so we can use them later
+ errata_details = []
+ for erratum in source_errata:
+ if erratum.get('advisory_name') in errata:
+ errata_details.append(erratum)
+
# get the packages that resolve these errata so we can add them
# to the channel afterwards
package_ids = []
@@ -613,9 +619,8 @@ def do_softwarechannel_adderrata(self, args):
logging.warning('No errata to add')
return
- print 'Errata'
- print '------'
- print '\n'.join(sorted(errata))
+ # show the user which errata will be added
+ print_errata_list(errata_details)
print
print 'Packages'
@@ -628,12 +633,15 @@ def do_softwarechannel_adderrata(self, args):
if not self.user_confirm('Add these errata and packages [y/N]:'): return
- # add the errata to the destination channel
- logging.debug('Cloning errata into %s' % dest_channel)
- self.client.errata.clone(self.session, dest_channel, errata)
+ # clone each erratum individually because the process is slow and it can
+ # lead to timeouts on the server
+ logging.info('Cloning errata into %s' % dest_channel)
+ for erratum in errata:
+ logging.debug('Cloning %s' % erratum)
+ self.client.errata.clone(self.session, dest_channel, [erratum])
# add the affected packages to the channel
- logging.debug('Adding required packages to %s' % dest_channel)
+ logging.info('Adding required packages to %s' % dest_channel)
self.client.channel.software.addPackages(self.session,
dest_channel,
package_ids)
commit 5658c2cb7061a0eb4a07a12f283dd0f36cfbafaf
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 12:12:45 2010 -0400
spacecmd: allow --debug to be passed multiple times
diff --git a/spacecmd/src/bin/spacecmd b/spacecmd/src/bin/spacecmd
index efb6e4b..e0f14f3 100755
--- a/spacecmd/src/bin/spacecmd
+++ b/spacecmd/src/bin/spacecmd
@@ -43,8 +43,8 @@ if __name__ == '__main__':
help='answer yes for all questions'),
Option('-q', '--quiet', action='store_true',
help='print only error messages'),
- Option('-d', '--debug', action='store_true',
- help='print debug messages'),
+ Option('-d', '--debug', action='count',
+ help='print debug messages (can be passed multiple times)'),
]
usage = 'usage: %prog [options] [command]'
@@ -66,7 +66,7 @@ if __name__ == '__main__':
config = SafeConfigParser()
config.read(conf_file)
- boolean_opts = [ 'nossl', 'debug' ]
+ boolean_opts = [ 'nossl' ]
string_opts = [ 'server', 'username', 'password' ]
for key in boolean_opts:
diff --git a/spacecmd/src/lib/misc.py b/spacecmd/src/lib/misc.py
index c522f7e..24dc3a4 100644
--- a/spacecmd/src/lib/misc.py
+++ b/spacecmd/src/lib/misc.py
@@ -191,9 +191,13 @@ def do_login(self, args):
server_url = '%s://%s/rpc/api' % (proto, server)
+ verbose_xmlrpc = False
+ if self.options.debug > 1:
+ verbose_xmlrpc = True
+
# connect to the server
logging.debug('Connecting to %s' % (server_url))
- self.client = xmlrpclib.Server(server_url, verbose = self.options.debug)
+ self.client = xmlrpclib.Server(server_url, verbose = verbose_xmlrpc)
# check the API to verify connectivity
try:
commit 8d4544fbdab9a5dcebdcc06a364866003e0db03f
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 12:10:31 2010 -0400
spacecmd: revert to the old-style of errata merging due to bugzilla 591291
This reverts commit e499a78102642416c30bd36a88a78bf6cde28d45.
diff --git a/spacecmd/src/lib/softwarechannel.py b/spacecmd/src/lib/softwarechannel.py
index b289aa9..b3caa1e 100644
--- a/spacecmd/src/lib/softwarechannel.py
+++ b/spacecmd/src/lib/softwarechannel.py
@@ -512,89 +512,131 @@ def do_softwarechannel_removepackages(self, args):
####################
+def help_softwarechannel_adderratabydate(self):
+ print 'softwarechannel_adderratabydate: Add errata from one channel ' + \
+ 'into another channel based on a date range'
+ print 'usage: softwarechannel_adderratabydate SOURCE DEST BEGINDATE ENDDATE'
+
+def complete_softwarechannel_adderratabydate(self, text, line, beg, end):
+ parts = line.split(' ')
+
+ if len(parts) <= 3:
+ return tab_completer(self.do_softwarechannel_list('', True),
+ text)
+
+def do_softwarechannel_adderratabydate(self, args):
+ args = parse_arguments(args)
+
+ if len(args) != 4:
+ self.help_softwarechannel_adderratabydate()
+ return
+
+ source_channel = args[0]
+ dest_channel = args[1]
+ begin_date = args[2]
+ end_date = args[3]
+
+ if not re.match('\d{8}', begin_date):
+ logging.error('%s is an invalid date' % begin_date)
+ return
+
+ if not re.match('\d{8}', end_date):
+ logging.error('%s is an invalid date' % end_date)
+ return
+
+ # get the errata that are in the given date range
+ logging.debug('Retrieving list of errata from source channel')
+ errata = \
+ self.client.channel.software.listErrata(self.session,
+ source_channel,
+ parse_time_input(begin_date),
+ parse_time_input(end_date))
+
+ if not len(errata):
+ logging.warning('No errata found between the given dates')
+ return
+
+ # call adderrata with the list of errata from the date range
+ return self.do_softwarechannel_adderrata('%s %s %s' % (
+ source_channel,
+ dest_channel,
+ ' '.join([ e.get('advisory_name') for e in errata ])))
+
+####################
+
def help_softwarechannel_adderrata(self):
print 'softwarechannel_adderrata: Add errata from one channel ' + \
'into another channel'
- print 'usage: softwarechannel_adderrata SOURCE DEST [BEGINDATE] [ENDDATE]'
+ print 'usage: softwarechannel_adderrata SOURCE DEST <ERRATA:search:XXX
...>'
def complete_softwarechannel_adderrata(self, text, line, beg, end):
parts = line.split(' ')
if len(parts) <= 3:
return tab_completer(self.do_softwarechannel_list('', True), text)
+ elif len(parts) > 3:
+ return self.tab_complete_errata(text)
def do_softwarechannel_adderrata(self, args):
args = parse_arguments(args)
- if len(args) < 2:
+ if len(args) < 3:
self.help_softwarechannel_adderrata()
return
source_channel = args[0]
dest_channel = args[1]
+ errata_wanted = self.expand_errata(args[2:])
- if len(args) >= 3:
- begin_date = parse_time_input(args[2])
- if not begin_date: return
- else:
- begin_date = None
+ logging.debug('Retrieving the list of errata from source channel')
+ source_errata = self.client.channel.software.listErrata(self.session,
+ source_channel)
- if len(args) == 4:
- end_date = parse_time_input(args[3])
- if not end_date: return
- else:
- end_date = parse_time_input('now')
+ errata = filter_results([ e.get('advisory_name') for e in source_errata ],
+ errata_wanted)
- logging.debug('Retrieving the list of errata from %s' % source_channel)
+ # get the packages that resolve these errata so we can add them
+ # to the channel afterwards
+ package_ids = []
+ for erratum in errata:
+ logging.debug('Retrieving packages for errata %s' % erratum)
- if begin_date:
- source_errata = self.client.channel.software.listErrata(self.session,
- source_channel,
- begin_date,
- end_date)
- else:
- source_errata = self.client.channel.software.listErrata(self.session,
- source_channel)
+ # get the packages affected by this errata
+ packages = self.client.errata.listPackages(self.session, erratum)
- logging.debug('Retrieving the list of errata from %s' % dest_channel)
- dest_errata = self.client.channel.software.listErrata(self.session,
- dest_channel)
+ # only add packages that exist in the source channel
+ for package in packages:
+ if source_channel in package.get('providing_channels'):
+ package_ids.append(package.get('id'))
- dest_errata_names = [ e.get('advisory_name') for e in dest_errata ]
+ if not len(errata):
+ logging.warning('No errata to add')
+ return
- # generate a list of errata likely to be merged by the API call
- likely = []
- for erratum in source_errata:
- if erratum.get('advisory_name') not in dest_errata_names:
- likely.append(erratum)
+ print 'Errata'
+ print '------'
+ print '\n'.join(sorted(errata))
- if len(likely):
- print_errata_list(likely)
- else:
- logging.warning('No errata to add to the channel')
- return
+ print
+ print 'Packages'
+ print '--------'
+ print '\n'.join(sorted([ self.get_package_name(p) for p in package_ids ]))
print
- print 'Total Errata: %i' % len(likely)
+ print 'Total Errata: %s' % str(len(errata)).rjust(3)
+ print 'Total Packages: %s' % str(len(package_ids)).rjust(3)
- if not self.user_confirm('Add these errata [y/N]:'): return
+ if not self.user_confirm('Add these errata and packages [y/N]:'): return
# add the errata to the destination channel
- logging.debug('Adding errata to %s' % dest_channel)
-
- if begin_date:
- added = self.client.channel.software.mergeErrata(self.session,
- source_channel,
- dest_channel,
- begin_date,
- end_date)
- else:
- added = self.client.channel.software.mergeErrata(self.session,
- source_channel,
- dest_channel)
+ logging.debug('Cloning errata into %s' % dest_channel)
+ self.client.errata.clone(self.session, dest_channel, errata)
- logging.info('The following errata were added to the channel:')
- print_errata_list(added)
+ # add the affected packages to the channel
+ logging.debug('Adding required packages to %s' % dest_channel)
+ self.client.channel.software.addPackages(self.session,
+ dest_channel,
+ package_ids)
# regenerate the errata cache since we just cloned errata
self.generate_errata_cache(True)
commit 5252253385cbb396b4e672bbb982183ff8a223fe
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 10:50:22 2010 -0400
spacecmd: cleanup column headers in report_outofdatesystems
diff --git a/spacecmd/src/lib/report.py b/spacecmd/src/lib/report.py
index 7efc33c..4798e65 100644
--- a/spacecmd/src/lib/report.py
+++ b/spacecmd/src/lib/report.py
@@ -101,8 +101,9 @@ def do_report_outofdatesystems(self, args):
report[system.get('name')] = len(packages)
if len(report):
- print '%s Packages' % ('System'.ljust(max_size))
- print '%s --------' % ('------'.ljust(max_size))
+ print '%s %s' % ('System'.ljust(max_size), 'Packages')
+ print ('-' * max_size) + ' --------'
+
for system in sorted(report):
print '%s %s' % \
(system.ljust(max_size), str(report[system]).rjust(3))
commit 4369f02fc32be1d0cb9494dd619d59e60beea13c
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 10:44:12 2010 -0400
spacecmd: show the last checkin time in report_inactivesystems
diff --git a/spacecmd/src/lib/report.py b/spacecmd/src/lib/report.py
index d6995f2..7efc33c 100644
--- a/spacecmd/src/lib/report.py
+++ b/spacecmd/src/lib/report.py
@@ -20,6 +20,7 @@
# NOTE: the 'self' variable is an instance of SpacewalkShell
+from operator import itemgetter
from spacecmd.utils import *
def help_report_entitlements(self):
@@ -55,20 +56,28 @@ def help_report_inactivesystems(self):
def do_report_inactivesystems(self, args):
args = parse_arguments(args)
+ # allow the user to set a limit on the number of days
if len(args) == 1:
try:
days = int(args[0])
except ValueError:
- days = 365
+ # default to a week when passed a bad argument
+ days = 7
systems = self.client.system.listInactiveSystems(self.session, days)
else:
+ # use the server's default period if no argument was passed
systems = self.client.system.listInactiveSystems(self.session)
- systems = [ s.get('name') for s in systems ]
-
if len(systems):
- print '\n'.join(sorted(systems))
+ max_size = max_length([ s.get('name') for s in systems ])
+
+ print '%s %s' % ('System'.ljust(max_size), 'Last
Checkin')
+ print ('-' * max_size) + ' ------------'
+
+ for s in sorted(systems, key=itemgetter('name')):
+ print '%s %s' % (s.get('name').ljust(max_size),
+ s.get('last_checkin'))
####################
@@ -79,11 +88,7 @@ def help_report_outofdatesystems(self):
def do_report_outofdatesystems(self, args):
systems = self.client.system.listOutOfDateSystems(self.session)
- #XXX: max(list, key=len) in >2.5
- max_size = 0
- for system in systems:
- size = len(system.get('name'))
- if size > max_size: max_size = size
+ max_size = max_length([ s.get('name') for s in systems ])
report = {}
for system in systems:
commit 5c8592f75a8d80dd0ccbca5c577f07c19b2c6cde
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 10:27:43 2010 -0400
spacecmd: clarify what 'Original State' means when cloning a software channel
diff --git a/spacecmd/src/lib/softwarechannel.py b/spacecmd/src/lib/softwarechannel.py
index f7f0481..b289aa9 100644
--- a/spacecmd/src/lib/softwarechannel.py
+++ b/spacecmd/src/lib/softwarechannel.py
@@ -378,7 +378,7 @@ def do_softwarechannel_clone(self, args):
details['gpg_id'] = prompt_user('GPG ID:')
details['gpg_fingerprint'] = prompt_user('GPG Fingerprint:')
- orig_state = self.user_confirm('Original State [y/N]:')
+ orig_state = self.user_confirm('Original State (No Errata) [y/N]:')
# remove empty strings from the structure
to_remove = []
commit 1842c55e29fc304eb18e0f4312f1aee3eb91073a
Author: Aron Parsons <aparsons(a)redhat.com>
Date: Mon Sep 20 10:26:31 2010 -0400
spacecmd: remove prompts for summary/description when creating software channels and
just use the name
diff --git a/spacecmd/src/lib/softwarechannel.py b/spacecmd/src/lib/softwarechannel.py
index c709d85..f7f0481 100644
--- a/spacecmd/src/lib/softwarechannel.py
+++ b/spacecmd/src/lib/softwarechannel.py
@@ -318,7 +318,7 @@ def help_softwarechannel_create(self):
def do_softwarechannel_create(self, args):
name = prompt_user('Channel Name:', noblank = True)
label = prompt_user('Channel Label:', noblank = True)
- summary = prompt_user('Summary:', noblank = True)
+ summary = name
print 'Base Channels'
print '-------------'
@@ -364,8 +364,8 @@ def do_softwarechannel_clone(self, args):
details['name'] = prompt_user('Channel Name:', noblank = True)
details['label'] = prompt_user('Channel Label:', noblank = True)
- details['summary'] = prompt_user('Summary:', noblank = True)
- details['description'] = prompt_user('Description:')
+ details['summary'] = details['name']
+ details['description'] = details['name']
print 'Base Channels:'
print '\n'.join(sorted(self.list_base_channels()))