backend/satellite_tools/Makefile | 4
backend/satellite_tools/satrm.py | 365 -----------------
backend/satellite_tools/spacewalk-remove-channel | 486 +++++++++++++++++++++++
backend/spacewalk-backend.spec | 2
rel-eng/packages/spacewalk-admin | 2
spacewalk/admin/spacewalk-admin.spec | 7
6 files changed, 496 insertions(+), 370 deletions(-)
New commits:
commit 7c61adf093cacdc669779ded088e7f982b8bf326
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Tue Feb 16 16:51:15 2010 -0500
Automatic commit of package [spacewalk-admin] release [0.9.1-1].
diff --git a/rel-eng/packages/spacewalk-admin b/rel-eng/packages/spacewalk-admin
index adcf35c..7dadac8 100644
--- a/rel-eng/packages/spacewalk-admin
+++ b/rel-eng/packages/spacewalk-admin
@@ -1 +1 @@
-0.8.1-1 spacewalk/admin/
+0.9.1-1 spacewalk/admin/
diff --git a/spacewalk/admin/spacewalk-admin.spec b/spacewalk/admin/spacewalk-admin.spec
index 781cd9a..6120028 100644
--- a/spacewalk/admin/spacewalk-admin.spec
+++ b/spacewalk/admin/spacewalk-admin.spec
@@ -2,7 +2,7 @@
Summary: Various utility scripts and data files for RHN Satellite installations
Name: spacewalk-admin
URL:
https://fedorahosted.org/spacewalk
-Version: 0.9.0
+Version: 0.9.1
Release: 1%{?dist}
Source0:
https://fedorahosted.org/releases/s/p/spacewalk/%{name}-%{version}.tar.gz
License: GPLv2
@@ -58,6 +58,11 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man3/validate-sat-cert.3.gz
%changelog
+* Tue Feb 16 2010 Justin Sherrill <jsherril(a)redhat.com> 0.9.1-1
+- changing rhn-satellite service script to support tomcat6
+ (jsherril(a)redhat.com)
+- let's start Spacewalk 0.9 (michael.mraka(a)redhat.com)
+
* Fri Jan 15 2010 Michael Mraka <michael.mraka(a)redhat.com> 0.8.1-1
- rebuild for spacewalk 0.8
commit 43ac6f03c525ca979f85bbe58c8ad4b6ddedd9ed
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Tue Feb 16 16:48:46 2010 -0500
fixing wrong filename in spec file
diff --git a/backend/spacewalk-backend.spec b/backend/spacewalk-backend.spec
index 08e767d..c60cec7 100644
--- a/backend/spacewalk-backend.spec
+++ b/backend/spacewalk-backend.spec
@@ -556,7 +556,7 @@ rm -f %{rhnconf}/rhnSecret.py*
%attr(755,root,root) %{_bindir}/rhn-schema-stats
%attr(750,root,root) %{_bindir}/satpasswd
%attr(750,root,root) %{_bindir}/satwho
-%attr(750,root,root) %{_bindir}/rhn-remove-channel*
+%attr(750,root,root) %{_bindir}/spacewalk-remove-channel*
%{rhnroot}/satellite_tools/SequenceServer.py*
%{rhnroot}/satellite_tools/messages.py*
%{rhnroot}/satellite_tools/progress_bar.py*
commit c0346c9c20d590a861b8f9187baae4eec326656e
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Tue Feb 16 16:47:17 2010 -0500
removing satrm from makefile
diff --git a/backend/satellite_tools/Makefile b/backend/satellite_tools/Makefile
index 8d93d8f..c6fa0ca 100644
--- a/backend/satellite_tools/Makefile
+++ b/backend/satellite_tools/Makefile
@@ -8,7 +8,7 @@ TOP = ..
SUBDIR = satellite_tools
SUBDIRS = exporter disk_dumper accounts repo_plugins
FILES = __init__ connection constants diskImportLib messages \
- progress_bar req_channels satCerts satrm satsync syncCache \
+ progress_bar req_channels satCerts satsync syncCache \
sync_handlers rhn-entitlement-report\
syncLib SequenceServer xmlDiskDumper xmlDiskSource \
xmlSource xmlWireSource rhn_satellite_activate rhn_ssl_dbstore \
commit 3e8736a825172b1a4238462309b57139088580ba
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Tue Feb 16 16:46:02 2010 -0500
renaming satrm script and updateing spec file
diff --git a/backend/satellite_tools/Makefile b/backend/satellite_tools/Makefile
index e2d9c4b..8d93d8f 100644
--- a/backend/satellite_tools/Makefile
+++ b/backend/satellite_tools/Makefile
@@ -17,7 +17,7 @@ FILES = __init__ connection constants diskImportLib messages \
SCRIPTS = satellite-sync spacewalk-debug\
rhn-schema-version rhn-satellite-activate rhn-charsets \
rhn-ssl-dbstore update-packages rhn-db-stats rhn-schema-stats \
- spacewalk-repo-sync
+ spacewalk-repo-sync spacewalk-remove-channel
# check if we can build man pages
DOCBOOK = $(wildcard /usr/bin/docbook2man)
diff --git a/backend/satellite_tools/satrm.py b/backend/satellite_tools/satrm.py
deleted file mode 100644
index af06ba3..0000000
--- a/backend/satellite_tools/satrm.py
+++ /dev/null
@@ -1,486 +0,0 @@
-#!/usr/bin/python
-#
-# Module that removes channels from an installed satellite
-#
-#
-# Copyright (c) 2008--2010 Red Hat, Inc.
-#
-# This software is licensed to you under the GNU General Public License,
-# version 2 (GPLv2). There is NO WARRANTY for this software, express or
-# implied, including the implied warranties of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
-# along with this software; if not, see
-#
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
-#
-# Red Hat trademarks are not licensed under GPLv2. No permission is
-# granted to use or replicate Red Hat trademarks that are incorporated
-# in this software or its documentation.
-#
-
-import sys
-import string
-import os
-
-from progress_bar import ProgressBar
-from optparse import Option, OptionParser
-
-
-_LIBPATH = "/usr/share/rhn"
-# add to the path if need be
-if _LIBPATH not in sys.path:
- sys.path.append(_LIBPATH)
-
-from common import CFG, initCFG, initLOG, log_debug, log_error
-from server import rhnSQL
-
-options_table = [
- Option("-v", "--verbose", action="count",
- help="Increase verbosity"),
- Option("-c", "--channel", action="append",
- help="Delete this channel (can be present multiple times)"),
- Option("-u", "--unsubscribe", action="store_true",
- help="Unsubscribe systems registered to the specificed channels"),
- Option( "--force", action="store_true",
- help="Remove the channel packages from any other channels too"),
- Option( "--justdb", action="store_true",
- help="Delete only from the database, do not remove files from disk"),
- Option("-l", "--list", action="store_true",
- help="List defined channels and exit"),
-]
-
-
-def main():
- print UNSUPPORTED_WARN
-
- global options_table
- parser = OptionParser(option_list=options_table)
-
- (options, args) = parser.parse_args()
-
- if args:
- for arg in args:
- sys.stderr.write("Not a valid option ('%s'), try --help\n"
% arg)
- return -1
-
- if not (options.channel or options.list):
- sys.stderr.write("Nothing to do\n")
- sys.exit(0)
-
- initCFG('server')
- initLOG("stdout", options.verbose or 0)
-
- rhnSQL.initDB(CFG.DEFAULT_DB)
-
- dict_label, dict_parents = __listChannels()
- if options.list:
- for c in dict_label.keys():
- print c
- return
-
-
- # Verify if the channel is valid
- channels = {}
- for channel in options.channel:
- channels[channel] = None
-
- for channel in channels.keys():
- if not dict_label.has_key(channel):
- print "Unknown channel %s" % channel
- return -1
- # Sanity check: verify subchannels are deleted as well if base
- # channels are selected
- if not dict_parents.has_key(channel):
- continue
- # this channel is a parent channel?
- for subch in dict_parents[channel]:
- if not channels.has_key(subch):
- print "Error: cannot remove channel %s: subchannel %s exists"
%(
- channel, subch)
- return -1
-
- if __serverCheck(channels.keys(), options.unsubscribe):
- return -1
-
- if __kickstartCheck(channels.keys()):
- return -1
-
-
- try:
- delete_channels(channels.keys(), force=options.force,
- justdb=options.justdb)
- except:
- rhnSQL.rollback()
- raise
- rhnSQL.commit()
- return 0
-
-def __serverCheck(labels, unsubscribe):
- sql = """
- select distinct S.org_id, S.id, S.name
- from rhnChannel c inner join
- rhnServerChannel sc on c.id = sc.channel_id inner join
- rhnServer s on s.id = sc.server_id
- where c.label in (%s)
- """
- params, bind_params = _bind_many(labels)
- bind_params = string.join(bind_params, ', ')
- h = rhnSQL.prepare(sql % (bind_params))
- apply(h.execute, (), params)
- list = h.fetchall_dict()
- if not list:
- return 0
-
-
- if unsubscribe:
- return __unsubscribeServers(labels)
-
- print("The following systems are subscribed to one or more of the specified
channels:\n")
-
- print 'org_id'.ljust(8),
- print 'id'.ljust(14),
- print('name')
- print ("-"*32)
- for map in list:
- print str(map['org_id']).ljust(8),
- print str(map['id']).ljust(14),
- print(map['name'])
-
- return len(list)
-
-
-def __unsubscribeServers(labels):
- sql = """
- select distinct sc.server_id as server_id, C.id as channel_id, c.parent_channel
- from rhnChannel c inner join
- rhnServerChannel sc on c.id = sc.channel_id
- where c.label in (%s) order by C.parent_channel
- """
- params, bind_params = _bind_many(labels)
- bind_params = string.join(bind_params, ', ')
- h = rhnSQL.prepare(sql % (bind_params))
- apply(h.execute, (), params)
- list = h.fetchall_dict()
-
- print("Unsubscribing systems (" + str(len(list)) + "):")
- pb = ProgressBar(prompt='Unsubscribing: ', endTag=' -
complete\n',
- finalSize=len(list), finalBarLength=40, stream=sys.stdout)
- pb.printAll(1)
-
- for i in list:
- __unbsubscribeServer(i['server_id'], i['channel_id'])
- pb.addTo(1)
- pb.printIncrement()
- pb.printComplete()
-
-
-def __unbsubscribeServer(server_id, channel_id):
- sql = """
- call rhn_channel.unsubscribe_server(:server_id, :channel_id)
- """
- h = rhnSQL.prepare(sql)
- h.execute(server_id=server_id, channel_id=channel_id)
-
-
-def __kickstartCheck(labels):
- sql = """
- select K.org_id, K.label
- from rhnKSData K inner join
- rhnKickstartDefaults KD on KD.kickstart_id = K.id inner join
- rhnKickstartableTree KT on KT.id = KD.kstree_id inner join
- rhnChannel c on c.id = KT.channel_id
- where c.label in (%s)
- """
- params, bind_params = _bind_many(labels)
- bind_params = string.join(bind_params, ', ')
- h = rhnSQL.prepare(sql % (bind_params))
- apply(h.execute, (), params)
- list = h.fetchall_dict()
-
- if not list:
- return 0
-
- print("The following kickstarts are associated with one of the specified
channels. " +
- "Please remove these or change their associated base
channel.\n")
- print('org_id'.ljust(8)),
- print('label')
- print("-"*20)
- for map in list:
- print str(map['org_id']).ljust(8),
- print(map['label'])
-
- return len(list)
-
-
-def __listChannels():
- sql = """
- select c1.label, c2.label parent_channel
- from rhnChannel c1, rhnChannel c2
- where c1.parent_channel = c2.id (+)
- """
- h = rhnSQL.prepare(sql)
- h.execute()
- labels = {}
- parents = {}
- while 1:
- row = h.fetchone_dict()
- if not row:
- break
- parent_channel = row['parent_channel']
- labels[row['label']] = parent_channel
- if parent_channel:
- if not parents.has_key(parent_channel):
- parents[parent_channel] = []
- parents[parent_channel].append(row['label'])
-
- return labels, parents
-
-
-def delete_channels(channelLabels, force=0, justdb=0):
- # Get the package ids
- if not channelLabels:
- return
-
- rpms_ids = list_packages(channelLabels, force=force, sources=0)
- rpms_paths = _get_package_paths(rpms_ids, sources=0)
- srpms_ids = list_packages(channelLabels, force=force, sources=1)
- srpms_paths = _get_package_paths(srpms_ids, sources=1)
-
- _delete_srpms(srpms_ids)
- _delete_rpms(rpms_ids)
-
- if not justdb:
- _delete_files(rpms_paths + srpms_paths)
-
- # Get the channel ids
- h = rhnSQL.prepare("""
- select id, parent_channel
- from rhnChannel
- where label = :label
- order by parent_channel""")
- channel_ids = []
- for label in channelLabels:
- h.execute(label=label)
- row = h.fetchone_dict()
- if not row:
- break
- channel_id = row['id']
- if row['parent_channel']:
- # Subchannel, we have to remove it first
- channel_ids.insert(0, channel_id)
- else:
- channel_ids.append(channel_id)
-
- if not channel_ids:
- return
-
- indirect_tables = [
- ['rhnKickstartableTree', 'channel_id', 'rhnKSTreeFile',
'kstree_id'],
- ]
- query = """
- delete from %(table_2)s where %(link_field)s in (
- select id
- from %(table_1)s
- where %(channel_field)s = :channel_id
- )
- """
- for e in indirect_tables:
- args = {
- 'table_1' : e[0],
- 'channel_field' : e[1],
- 'table_2' : e[2],
- 'link_field' : e[3],
- }
- h = rhnSQL.prepare(query % args)
- h.executemany(channel_id=channel_ids)
-
- tables = [
- ['rhnErrataFileChannel', 'channel_id'],
- ['rhnChannelErrata', 'channel_id'],
- ['rhnChannelFamilyMembers', 'channel_id'],
- ['rhnChannelPackage', 'channel_id'],
- ['rhnDistChannelMap', 'channel_id'],
- ['rhnRegTokenChannels', 'channel_id'],
- ['rhnServerProfile', 'base_channel'],
- ['rhnKickstartableTree', 'channel_id'],
- ['rhnChannel', 'id'],
- ]
-
- query = "delete from %s where %s = :channel_id"
- for table, field in tables:
- log_debug(3, "Processing table %s" % table)
- h = rhnSQL.prepare(query % (table, field))
- h.executemany(channel_id=channel_ids)
-
-def list_packages(channelLabels, sources=0, force=0):
- "List the source ids for the channels"
- if sources:
- packages = "srpms"
- else:
- packages = "rpms"
- log_debug(3, "Listing %s" % packages)
- if not channelLabels:
- return []
-
- params, bind_params = _bind_many(channelLabels)
- bind_params = string.join(bind_params, ', ')
-
- if sources:
- templ = _templ_srpms()
- else:
- templ = _templ_rpms()
-
- if force:
- query = templ % ("", bind_params)
- else:
- query = """
- %s
- MINUS
- %s
- """ % (
- templ % ("", bind_params),
- templ % ("not", bind_params),
- )
- h = rhnSQL.prepare(query)
- apply(h.execute, (), params)
- return map(lambda x: x['id'], h.fetchall_dict() or [])
-
-def _templ_rpms():
- "Returns a template for querying rpms"
- log_debug(4, "Generating template for querying rpms")
- return """\
- select cp.package_id id
- from rhnChannel c, rhnChannelPackage cp
- where c.label %s in (%s)
- and cp.channel_id = c.id"""
-
-def _templ_srpms():
- "Returns a template for querying srpms"
- log_debug(4, "Generating template for querying srpms")
- return """\
- select ps.id id
- from rhnPackage p,
- rhnPackageSource ps,
- rhnChannelPackage cp,
- rhnChannel c
- where c.label %s in (%s)
- and c.id = cp.channel_id
- and cp.package_id = p.id
- and p.source_rpm_id = ps.source_rpm_id
- and ((p.org_id is null and ps.org_id is null) or
- p.org_id = ps.org_id)"""
-
-def _delete_srpms(srcPackageIds):
- """Blow away rhnPackageSource and rhnFile entries.
- """
- if not srcPackageIds:
- return
- # nuke the rhnPackageSource entry
- h = rhnSQL.prepare("""
- delete
- from rhnPackageSource
- where id = :id
- """)
- count = h.executemany(id=srcPackageIds)
- if not count:
- count = 0
- log_debug(2, "Successfully deleted %s/%s source package ids" % (
- count, len(srcPackageIds)))
-
-def _delete_rpms(packageIds):
- if not packageIds:
- return
- group = 300
- toDel = packageIds[:]
- print "Deleting package metadata (" + str(len(toDel)) + "):"
- pb = ProgressBar(prompt='Removing: ', endTag=' - complete',
- finalSize=len(packageIds), finalBarLength=40, stream=sys.stdout)
- pb.printAll(1)
-
- while len(toDel) > 0:
- _delete_rpm_group(toDel[:group])
- del toDel[:group]
- pb.addTo(group)
- pb.printIncrement()
- pb.printComplete()
-
-def _delete_rpm_group(packageIds):
-
- references = [
- 'rhnChannelPackage',
- 'rhnErrataPackage',
- 'rhnErrataPackageTMP',
- 'rhnPackageChangelog',
- 'rhnPackageConflicts',
- 'rhnPackageFile',
- 'rhnPackageObsoletes',
- 'rhnPackageProvides',
- 'rhnPackageRequires',
- 'rhnServerNeededCache',
- ]
- deleteStatement = "delete from %s where package_id = :package_id"
- for table in references:
- h = rhnSQL.prepare(deleteStatement % table)
- count = h.executemany(package_id=packageIds)
- log_debug(3, "Deleted from %s: %d rows" % (table, count))
- deleteStatement = "delete from rhnPackage where id = :package_id"
- h = rhnSQL.prepare(deleteStatement)
- count = h.executemany(package_id=packageIds)
- if count:
- log_debug(2, "DELETED package id %s" % str(packageIds))
- else:
- log_error("No such package id %s" % str(packageIds))
- rhnSQL.commit()
-
-def _delete_files(relpaths):
- for relpath in relpaths:
- path = os.path.join(CFG.MOUNT_POINT, relpath)
- if not os.path.exists(path):
- log_debug(1, "Not removing %s: no such file" % path)
- continue
- try:
- os.unlink(path)
- except OSError:
- log_debug(1, "Error unlinking %s;" % path)
-
-def _bind_many(l):
- h = {}
- lr = []
- for i in range(len(l)):
- key = 'p_%s' % i
- h[key] = l[i]
- lr.append(':' + key)
- return h, lr
-
-def _get_package_paths(package_ids, sources=0):
- if sources:
- table = "rhnPackageSource"
- else:
- table = "rhnPackage"
- h = rhnSQL.prepare("select path from %s where id = :package_id" % table)
- pdict = {}
- for package_id in package_ids:
- h.execute(package_id=package_id)
- row = h.fetchone_dict()
- if not row:
- continue
- if not row['path']:
- continue
- pdict[row['path']] = None
-
- return pdict.keys()
-
-if __name__ == '__main__':
- try:
- sys.exit(main() or 0)
- except KeyboardInterrupt:
- sys.stderr.write("\nUser interrupted process.\n")
- sys.exit(0)
- except SystemExit:
- # Normal exit
- raise
- except Exception, e:
- sys.stderr.write("\nERROR: unhandled exception occurred: (%s).\n" % e)
- import traceback
- traceback.print_exc()
- sys.exit(-1)
-
diff --git a/backend/satellite_tools/spacewalk-remove-channel
b/backend/satellite_tools/spacewalk-remove-channel
new file mode 100644
index 0000000..af06ba3
--- /dev/null
+++ b/backend/satellite_tools/spacewalk-remove-channel
@@ -0,0 +1,486 @@
+#!/usr/bin/python
+#
+# Module that removes channels from an installed satellite
+#
+#
+# Copyright (c) 2008--2010 Red Hat, Inc.
+#
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+#
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# Red Hat trademarks are not licensed under GPLv2. No permission is
+# granted to use or replicate Red Hat trademarks that are incorporated
+# in this software or its documentation.
+#
+
+import sys
+import string
+import os
+
+from progress_bar import ProgressBar
+from optparse import Option, OptionParser
+
+
+_LIBPATH = "/usr/share/rhn"
+# add to the path if need be
+if _LIBPATH not in sys.path:
+ sys.path.append(_LIBPATH)
+
+from common import CFG, initCFG, initLOG, log_debug, log_error
+from server import rhnSQL
+
+options_table = [
+ Option("-v", "--verbose", action="count",
+ help="Increase verbosity"),
+ Option("-c", "--channel", action="append",
+ help="Delete this channel (can be present multiple times)"),
+ Option("-u", "--unsubscribe", action="store_true",
+ help="Unsubscribe systems registered to the specificed channels"),
+ Option( "--force", action="store_true",
+ help="Remove the channel packages from any other channels too"),
+ Option( "--justdb", action="store_true",
+ help="Delete only from the database, do not remove files from disk"),
+ Option("-l", "--list", action="store_true",
+ help="List defined channels and exit"),
+]
+
+
+def main():
+ print UNSUPPORTED_WARN
+
+ global options_table
+ parser = OptionParser(option_list=options_table)
+
+ (options, args) = parser.parse_args()
+
+ if args:
+ for arg in args:
+ sys.stderr.write("Not a valid option ('%s'), try --help\n"
% arg)
+ return -1
+
+ if not (options.channel or options.list):
+ sys.stderr.write("Nothing to do\n")
+ sys.exit(0)
+
+ initCFG('server')
+ initLOG("stdout", options.verbose or 0)
+
+ rhnSQL.initDB(CFG.DEFAULT_DB)
+
+ dict_label, dict_parents = __listChannels()
+ if options.list:
+ for c in dict_label.keys():
+ print c
+ return
+
+
+ # Verify if the channel is valid
+ channels = {}
+ for channel in options.channel:
+ channels[channel] = None
+
+ for channel in channels.keys():
+ if not dict_label.has_key(channel):
+ print "Unknown channel %s" % channel
+ return -1
+ # Sanity check: verify subchannels are deleted as well if base
+ # channels are selected
+ if not dict_parents.has_key(channel):
+ continue
+ # this channel is a parent channel?
+ for subch in dict_parents[channel]:
+ if not channels.has_key(subch):
+ print "Error: cannot remove channel %s: subchannel %s exists"
%(
+ channel, subch)
+ return -1
+
+ if __serverCheck(channels.keys(), options.unsubscribe):
+ return -1
+
+ if __kickstartCheck(channels.keys()):
+ return -1
+
+
+ try:
+ delete_channels(channels.keys(), force=options.force,
+ justdb=options.justdb)
+ except:
+ rhnSQL.rollback()
+ raise
+ rhnSQL.commit()
+ return 0
+
+def __serverCheck(labels, unsubscribe):
+ sql = """
+ select distinct S.org_id, S.id, S.name
+ from rhnChannel c inner join
+ rhnServerChannel sc on c.id = sc.channel_id inner join
+ rhnServer s on s.id = sc.server_id
+ where c.label in (%s)
+ """
+ params, bind_params = _bind_many(labels)
+ bind_params = string.join(bind_params, ', ')
+ h = rhnSQL.prepare(sql % (bind_params))
+ apply(h.execute, (), params)
+ list = h.fetchall_dict()
+ if not list:
+ return 0
+
+
+ if unsubscribe:
+ return __unsubscribeServers(labels)
+
+ print("The following systems are subscribed to one or more of the specified
channels:\n")
+
+ print 'org_id'.ljust(8),
+ print 'id'.ljust(14),
+ print('name')
+ print ("-"*32)
+ for map in list:
+ print str(map['org_id']).ljust(8),
+ print str(map['id']).ljust(14),
+ print(map['name'])
+
+ return len(list)
+
+
+def __unsubscribeServers(labels):
+ sql = """
+ select distinct sc.server_id as server_id, C.id as channel_id, c.parent_channel
+ from rhnChannel c inner join
+ rhnServerChannel sc on c.id = sc.channel_id
+ where c.label in (%s) order by C.parent_channel
+ """
+ params, bind_params = _bind_many(labels)
+ bind_params = string.join(bind_params, ', ')
+ h = rhnSQL.prepare(sql % (bind_params))
+ apply(h.execute, (), params)
+ list = h.fetchall_dict()
+
+ print("Unsubscribing systems (" + str(len(list)) + "):")
+ pb = ProgressBar(prompt='Unsubscribing: ', endTag=' -
complete\n',
+ finalSize=len(list), finalBarLength=40, stream=sys.stdout)
+ pb.printAll(1)
+
+ for i in list:
+ __unbsubscribeServer(i['server_id'], i['channel_id'])
+ pb.addTo(1)
+ pb.printIncrement()
+ pb.printComplete()
+
+
+def __unbsubscribeServer(server_id, channel_id):
+ sql = """
+ call rhn_channel.unsubscribe_server(:server_id, :channel_id)
+ """
+ h = rhnSQL.prepare(sql)
+ h.execute(server_id=server_id, channel_id=channel_id)
+
+
+def __kickstartCheck(labels):
+ sql = """
+ select K.org_id, K.label
+ from rhnKSData K inner join
+ rhnKickstartDefaults KD on KD.kickstart_id = K.id inner join
+ rhnKickstartableTree KT on KT.id = KD.kstree_id inner join
+ rhnChannel c on c.id = KT.channel_id
+ where c.label in (%s)
+ """
+ params, bind_params = _bind_many(labels)
+ bind_params = string.join(bind_params, ', ')
+ h = rhnSQL.prepare(sql % (bind_params))
+ apply(h.execute, (), params)
+ list = h.fetchall_dict()
+
+ if not list:
+ return 0
+
+ print("The following kickstarts are associated with one of the specified
channels. " +
+ "Please remove these or change their associated base
channel.\n")
+ print('org_id'.ljust(8)),
+ print('label')
+ print("-"*20)
+ for map in list:
+ print str(map['org_id']).ljust(8),
+ print(map['label'])
+
+ return len(list)
+
+
+def __listChannels():
+ sql = """
+ select c1.label, c2.label parent_channel
+ from rhnChannel c1, rhnChannel c2
+ where c1.parent_channel = c2.id (+)
+ """
+ h = rhnSQL.prepare(sql)
+ h.execute()
+ labels = {}
+ parents = {}
+ while 1:
+ row = h.fetchone_dict()
+ if not row:
+ break
+ parent_channel = row['parent_channel']
+ labels[row['label']] = parent_channel
+ if parent_channel:
+ if not parents.has_key(parent_channel):
+ parents[parent_channel] = []
+ parents[parent_channel].append(row['label'])
+
+ return labels, parents
+
+
+def delete_channels(channelLabels, force=0, justdb=0):
+ # Get the package ids
+ if not channelLabels:
+ return
+
+ rpms_ids = list_packages(channelLabels, force=force, sources=0)
+ rpms_paths = _get_package_paths(rpms_ids, sources=0)
+ srpms_ids = list_packages(channelLabels, force=force, sources=1)
+ srpms_paths = _get_package_paths(srpms_ids, sources=1)
+
+ _delete_srpms(srpms_ids)
+ _delete_rpms(rpms_ids)
+
+ if not justdb:
+ _delete_files(rpms_paths + srpms_paths)
+
+ # Get the channel ids
+ h = rhnSQL.prepare("""
+ select id, parent_channel
+ from rhnChannel
+ where label = :label
+ order by parent_channel""")
+ channel_ids = []
+ for label in channelLabels:
+ h.execute(label=label)
+ row = h.fetchone_dict()
+ if not row:
+ break
+ channel_id = row['id']
+ if row['parent_channel']:
+ # Subchannel, we have to remove it first
+ channel_ids.insert(0, channel_id)
+ else:
+ channel_ids.append(channel_id)
+
+ if not channel_ids:
+ return
+
+ indirect_tables = [
+ ['rhnKickstartableTree', 'channel_id', 'rhnKSTreeFile',
'kstree_id'],
+ ]
+ query = """
+ delete from %(table_2)s where %(link_field)s in (
+ select id
+ from %(table_1)s
+ where %(channel_field)s = :channel_id
+ )
+ """
+ for e in indirect_tables:
+ args = {
+ 'table_1' : e[0],
+ 'channel_field' : e[1],
+ 'table_2' : e[2],
+ 'link_field' : e[3],
+ }
+ h = rhnSQL.prepare(query % args)
+ h.executemany(channel_id=channel_ids)
+
+ tables = [
+ ['rhnErrataFileChannel', 'channel_id'],
+ ['rhnChannelErrata', 'channel_id'],
+ ['rhnChannelFamilyMembers', 'channel_id'],
+ ['rhnChannelPackage', 'channel_id'],
+ ['rhnDistChannelMap', 'channel_id'],
+ ['rhnRegTokenChannels', 'channel_id'],
+ ['rhnServerProfile', 'base_channel'],
+ ['rhnKickstartableTree', 'channel_id'],
+ ['rhnChannel', 'id'],
+ ]
+
+ query = "delete from %s where %s = :channel_id"
+ for table, field in tables:
+ log_debug(3, "Processing table %s" % table)
+ h = rhnSQL.prepare(query % (table, field))
+ h.executemany(channel_id=channel_ids)
+
+def list_packages(channelLabels, sources=0, force=0):
+ "List the source ids for the channels"
+ if sources:
+ packages = "srpms"
+ else:
+ packages = "rpms"
+ log_debug(3, "Listing %s" % packages)
+ if not channelLabels:
+ return []
+
+ params, bind_params = _bind_many(channelLabels)
+ bind_params = string.join(bind_params, ', ')
+
+ if sources:
+ templ = _templ_srpms()
+ else:
+ templ = _templ_rpms()
+
+ if force:
+ query = templ % ("", bind_params)
+ else:
+ query = """
+ %s
+ MINUS
+ %s
+ """ % (
+ templ % ("", bind_params),
+ templ % ("not", bind_params),
+ )
+ h = rhnSQL.prepare(query)
+ apply(h.execute, (), params)
+ return map(lambda x: x['id'], h.fetchall_dict() or [])
+
+def _templ_rpms():
+ "Returns a template for querying rpms"
+ log_debug(4, "Generating template for querying rpms")
+ return """\
+ select cp.package_id id
+ from rhnChannel c, rhnChannelPackage cp
+ where c.label %s in (%s)
+ and cp.channel_id = c.id"""
+
+def _templ_srpms():
+ "Returns a template for querying srpms"
+ log_debug(4, "Generating template for querying srpms")
+ return """\
+ select ps.id id
+ from rhnPackage p,
+ rhnPackageSource ps,
+ rhnChannelPackage cp,
+ rhnChannel c
+ where c.label %s in (%s)
+ and c.id = cp.channel_id
+ and cp.package_id = p.id
+ and p.source_rpm_id = ps.source_rpm_id
+ and ((p.org_id is null and ps.org_id is null) or
+ p.org_id = ps.org_id)"""
+
+def _delete_srpms(srcPackageIds):
+ """Blow away rhnPackageSource and rhnFile entries.
+ """
+ if not srcPackageIds:
+ return
+ # nuke the rhnPackageSource entry
+ h = rhnSQL.prepare("""
+ delete
+ from rhnPackageSource
+ where id = :id
+ """)
+ count = h.executemany(id=srcPackageIds)
+ if not count:
+ count = 0
+ log_debug(2, "Successfully deleted %s/%s source package ids" % (
+ count, len(srcPackageIds)))
+
+def _delete_rpms(packageIds):
+ if not packageIds:
+ return
+ group = 300
+ toDel = packageIds[:]
+ print "Deleting package metadata (" + str(len(toDel)) + "):"
+ pb = ProgressBar(prompt='Removing: ', endTag=' - complete',
+ finalSize=len(packageIds), finalBarLength=40, stream=sys.stdout)
+ pb.printAll(1)
+
+ while len(toDel) > 0:
+ _delete_rpm_group(toDel[:group])
+ del toDel[:group]
+ pb.addTo(group)
+ pb.printIncrement()
+ pb.printComplete()
+
+def _delete_rpm_group(packageIds):
+
+ references = [
+ 'rhnChannelPackage',
+ 'rhnErrataPackage',
+ 'rhnErrataPackageTMP',
+ 'rhnPackageChangelog',
+ 'rhnPackageConflicts',
+ 'rhnPackageFile',
+ 'rhnPackageObsoletes',
+ 'rhnPackageProvides',
+ 'rhnPackageRequires',
+ 'rhnServerNeededCache',
+ ]
+ deleteStatement = "delete from %s where package_id = :package_id"
+ for table in references:
+ h = rhnSQL.prepare(deleteStatement % table)
+ count = h.executemany(package_id=packageIds)
+ log_debug(3, "Deleted from %s: %d rows" % (table, count))
+ deleteStatement = "delete from rhnPackage where id = :package_id"
+ h = rhnSQL.prepare(deleteStatement)
+ count = h.executemany(package_id=packageIds)
+ if count:
+ log_debug(2, "DELETED package id %s" % str(packageIds))
+ else:
+ log_error("No such package id %s" % str(packageIds))
+ rhnSQL.commit()
+
+def _delete_files(relpaths):
+ for relpath in relpaths:
+ path = os.path.join(CFG.MOUNT_POINT, relpath)
+ if not os.path.exists(path):
+ log_debug(1, "Not removing %s: no such file" % path)
+ continue
+ try:
+ os.unlink(path)
+ except OSError:
+ log_debug(1, "Error unlinking %s;" % path)
+
+def _bind_many(l):
+ h = {}
+ lr = []
+ for i in range(len(l)):
+ key = 'p_%s' % i
+ h[key] = l[i]
+ lr.append(':' + key)
+ return h, lr
+
+def _get_package_paths(package_ids, sources=0):
+ if sources:
+ table = "rhnPackageSource"
+ else:
+ table = "rhnPackage"
+ h = rhnSQL.prepare("select path from %s where id = :package_id" % table)
+ pdict = {}
+ for package_id in package_ids:
+ h.execute(package_id=package_id)
+ row = h.fetchone_dict()
+ if not row:
+ continue
+ if not row['path']:
+ continue
+ pdict[row['path']] = None
+
+ return pdict.keys()
+
+if __name__ == '__main__':
+ try:
+ sys.exit(main() or 0)
+ except KeyboardInterrupt:
+ sys.stderr.write("\nUser interrupted process.\n")
+ sys.exit(0)
+ except SystemExit:
+ # Normal exit
+ raise
+ except Exception, e:
+ sys.stderr.write("\nERROR: unhandled exception occurred: (%s).\n" % e)
+ import traceback
+ traceback.print_exc()
+ sys.exit(-1)
+
diff --git a/backend/spacewalk-backend.spec b/backend/spacewalk-backend.spec
index 6b84412..08e767d 100644
--- a/backend/spacewalk-backend.spec
+++ b/backend/spacewalk-backend.spec
@@ -556,11 +556,11 @@ rm -f %{rhnconf}/rhnSecret.py*
%attr(755,root,root) %{_bindir}/rhn-schema-stats
%attr(750,root,root) %{_bindir}/satpasswd
%attr(750,root,root) %{_bindir}/satwho
+%attr(750,root,root) %{_bindir}/rhn-remove-channel*
%{rhnroot}/satellite_tools/SequenceServer.py*
%{rhnroot}/satellite_tools/messages.py*
%{rhnroot}/satellite_tools/progress_bar.py*
%{rhnroot}/satellite_tools/req_channels.py*
-%{rhnroot}/satellite_tools/satrm.py*
%{rhnroot}/satellite_tools/rhn-entitlement-report.py*
%{rhnroot}/satellite_tools/satsync.py*
%{rhnroot}/satellite_tools/satCerts.py*
commit 259ddb406b3ed52a6f5f0a06314b9e138c6758e1
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Tue Feb 16 16:45:06 2010 -0500
updating satrm.py with better usability and fixing several bugs
diff --git a/backend/satellite_tools/satrm.py b/backend/satellite_tools/satrm.py
index dfb642f..af06ba3 100644
--- a/backend/satellite_tools/satrm.py
+++ b/backend/satellite_tools/satrm.py
@@ -20,21 +20,26 @@
import sys
import string
import os
+
+from progress_bar import ProgressBar
from optparse import Option, OptionParser
+
+
+_LIBPATH = "/usr/share/rhn"
+# add to the path if need be
+if _LIBPATH not in sys.path:
+ sys.path.append(_LIBPATH)
+
from common import CFG, initCFG, initLOG, log_debug, log_error
from server import rhnSQL
-UNSUPPORTED_WARN = """
-NOTE: This method is not maintained or supported by Red Hat but can be
-used if necessary precautions are taken. A database backup before removal
-is recommended.
-"""
-
options_table = [
Option("-v", "--verbose", action="count",
help="Increase verbosity"),
Option("-c", "--channel", action="append",
help="Delete this channel (can be present multiple times)"),
+ Option("-u", "--unsubscribe", action="store_true",
+ help="Unsubscribe systems registered to the specificed channels"),
Option( "--force", action="store_true",
help="Remove the channel packages from any other channels too"),
Option( "--justdb", action="store_true",
@@ -93,8 +98,12 @@ def main():
channel, subch)
return -1
- # Are we attempting to remove a parent channel while there are still
- # references
+ if __serverCheck(channels.keys(), options.unsubscribe):
+ return -1
+
+ if __kickstartCheck(channels.keys()):
+ return -1
+
try:
delete_channels(channels.keys(), force=options.force,
@@ -105,6 +114,102 @@ def main():
rhnSQL.commit()
return 0
+def __serverCheck(labels, unsubscribe):
+ sql = """
+ select distinct S.org_id, S.id, S.name
+ from rhnChannel c inner join
+ rhnServerChannel sc on c.id = sc.channel_id inner join
+ rhnServer s on s.id = sc.server_id
+ where c.label in (%s)
+ """
+ params, bind_params = _bind_many(labels)
+ bind_params = string.join(bind_params, ', ')
+ h = rhnSQL.prepare(sql % (bind_params))
+ apply(h.execute, (), params)
+ list = h.fetchall_dict()
+ if not list:
+ return 0
+
+
+ if unsubscribe:
+ return __unsubscribeServers(labels)
+
+ print("The following systems are subscribed to one or more of the specified
channels:\n")
+
+ print 'org_id'.ljust(8),
+ print 'id'.ljust(14),
+ print('name')
+ print ("-"*32)
+ for map in list:
+ print str(map['org_id']).ljust(8),
+ print str(map['id']).ljust(14),
+ print(map['name'])
+
+ return len(list)
+
+
+def __unsubscribeServers(labels):
+ sql = """
+ select distinct sc.server_id as server_id, C.id as channel_id, c.parent_channel
+ from rhnChannel c inner join
+ rhnServerChannel sc on c.id = sc.channel_id
+ where c.label in (%s) order by C.parent_channel
+ """
+ params, bind_params = _bind_many(labels)
+ bind_params = string.join(bind_params, ', ')
+ h = rhnSQL.prepare(sql % (bind_params))
+ apply(h.execute, (), params)
+ list = h.fetchall_dict()
+
+ print("Unsubscribing systems (" + str(len(list)) + "):")
+ pb = ProgressBar(prompt='Unsubscribing: ', endTag=' -
complete\n',
+ finalSize=len(list), finalBarLength=40, stream=sys.stdout)
+ pb.printAll(1)
+
+ for i in list:
+ __unbsubscribeServer(i['server_id'], i['channel_id'])
+ pb.addTo(1)
+ pb.printIncrement()
+ pb.printComplete()
+
+
+def __unbsubscribeServer(server_id, channel_id):
+ sql = """
+ call rhn_channel.unsubscribe_server(:server_id, :channel_id)
+ """
+ h = rhnSQL.prepare(sql)
+ h.execute(server_id=server_id, channel_id=channel_id)
+
+
+def __kickstartCheck(labels):
+ sql = """
+ select K.org_id, K.label
+ from rhnKSData K inner join
+ rhnKickstartDefaults KD on KD.kickstart_id = K.id inner join
+ rhnKickstartableTree KT on KT.id = KD.kstree_id inner join
+ rhnChannel c on c.id = KT.channel_id
+ where c.label in (%s)
+ """
+ params, bind_params = _bind_many(labels)
+ bind_params = string.join(bind_params, ', ')
+ h = rhnSQL.prepare(sql % (bind_params))
+ apply(h.execute, (), params)
+ list = h.fetchall_dict()
+
+ if not list:
+ return 0
+
+ print("The following kickstarts are associated with one of the specified
channels. " +
+ "Please remove these or change their associated base
channel.\n")
+ print('org_id'.ljust(8)),
+ print('label')
+ print("-"*20)
+ for map in list:
+ print str(map['org_id']).ljust(8),
+ print(map['label'])
+
+ return len(list)
+
def __listChannels():
sql = """
@@ -195,7 +300,6 @@ def delete_channels(channelLabels, force=0, justdb=0):
['rhnChannelPackage', 'channel_id'],
['rhnDistChannelMap', 'channel_id'],
['rhnRegTokenChannels', 'channel_id'],
- ['rhnServerChannel', 'channel_id'],
['rhnServerProfile', 'base_channel'],
['rhnKickstartableTree', 'channel_id'],
['rhnChannel', 'id'],
@@ -285,6 +389,21 @@ def _delete_srpms(srcPackageIds):
def _delete_rpms(packageIds):
if not packageIds:
return
+ group = 300
+ toDel = packageIds[:]
+ print "Deleting package metadata (" + str(len(toDel)) + "):"
+ pb = ProgressBar(prompt='Removing: ', endTag=' - complete',
+ finalSize=len(packageIds), finalBarLength=40, stream=sys.stdout)
+ pb.printAll(1)
+
+ while len(toDel) > 0:
+ _delete_rpm_group(toDel[:group])
+ del toDel[:group]
+ pb.addTo(group)
+ pb.printIncrement()
+ pb.printComplete()
+
+def _delete_rpm_group(packageIds):
references = [
'rhnChannelPackage',
@@ -310,6 +429,7 @@ def _delete_rpms(packageIds):
log_debug(2, "DELETED package id %s" % str(packageIds))
else:
log_error("No such package id %s" % str(packageIds))
+ rhnSQL.commit()
def _delete_files(relpaths):
for relpath in relpaths:
@@ -320,8 +440,7 @@ def _delete_files(relpaths):
try:
os.unlink(path)
except OSError:
- print "Error unlinking %s; rolling back" % path
- raise
+ log_debug(1, "Error unlinking %s;" % path)
def _bind_many(l):
h = {}
@@ -361,5 +480,7 @@ if __name__ == '__main__':
raise
except Exception, e:
sys.stderr.write("\nERROR: unhandled exception occurred: (%s).\n" % e)
+ import traceback
+ traceback.print_exc()
sys.exit(-1)