utils/cloneByDate.py | 57 +++++++++++++++++++++++++++---------------
utils/spacewalk-clone-by-date | 36 ++++++++++++++++++++++----
2 files changed, 68 insertions(+), 25 deletions(-)
New commits:
commit ed4d17a4427a44f0e52619fc2c4ca666dc28fbf7
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Mon Jan 30 10:06:17 2012 -0500
moving dep solving to channel tree instead of individual channels
diff --git a/utils/cloneByDate.py b/utils/cloneByDate.py
index d39438d..106be52 100644
--- a/utils/cloneByDate.py
+++ b/utils/cloneByDate.py
@@ -64,7 +64,7 @@ def main(options):
for channel_list in options.channels:
tree_cloner = ChannelTreeCloner(channel_list, xmlrpc, db, options.to_date)
cloners.append(tree_cloner)
- needed_channels += tree_cloner.needing_create()
+ needed_channels += tree_cloner.needing_create().values()
if len(needed_channels) > 0:
print "\nBy continuing the following channels will be created: "
@@ -113,13 +113,14 @@ class ChannelTreeCloner:
cloner = ChannelCloner(from_label, to_label, self.to_date, self.remote_api,
self.db_api)
self.cloners.append(cloner)
+ #returns a trimmed down version of channel_map where the value needs creating
def needing_create(self):
- to_ret = []
+ to_create = {}
existing = self.remote_api.list_channel_labels()
- for label in self.channel_map.values():
- if existing.count(label) == 0:
- to_ret.append(label)
- return to_ret
+ for src, dest in self.channel_map.items():
+ if dest not in existing:
+ to_create[src] = dest
+ return to_create
def pending(self):
total = 0
@@ -127,23 +128,33 @@ class ChannelTreeCloner:
total += cloner.pending()
return total
+ def find_cloner(self, src_label):
+ for cloner in self.cloners:
+ if cloner.src_label() == src_label:
+ return cloner
+
def create_channels(self):
to_create = self.needing_create()
+
if len(to_create) == 0:
return
dest_parent = self.channel_map[self.src_parent]
nvreas = []
- if to_create.count(dest_parent) > 0:
+
+ #clone the destination parent if it doesn't exist
+ if dest_parent in to_create.values():
self.remote_api.clone_channel(self.src_parent, dest_parent, None)
- to_create.remove(dest_parent)
- cloner = self.cloners[0]
+ del to_create[self.src_parent]
+ cloner = self.find_cloner(self.src_parent)
nvreas += [ pkg['nvrea'] for pkg in
cloner.reset_new_pkgs().values()]
-
+ #clone the children
for cloner in self.cloners:
- if cloner.dest_label() in to_create:
+ if cloner.dest_label() in to_create.values():
self.remote_api.clone_channel(cloner.src_label(), cloner.dest_label(),
dest_parent)
nvreas += [ pkg['nvrea'] for pkg in
cloner.reset_new_pkgs().values() ]
- self.dep_solve(nvreas, labels=to_create)
+
+ #dep solve all added packages with the parent channel
+ self.dep_solve(nvreas, labels=(to_create.keys() + [self.src_parent]))
def validate_source_channels(self):
@@ -195,17 +206,17 @@ class ChannelTreeCloner:
for cloner in self.cloners:
cloner.process()
added_pkgs += cloner.pkg_diff()
- self.dep_solve(added_pkgs)
+ self.dep_solve([pkg['nvrea'] for pkg in added_pkgs])
- def dep_solve(self, nvrea_list, labels=None):
+ def dep_solve(self, nvrea_list, labels=None):
if not labels:
labels = self.channel_map.keys()
repos = [{"id":label, "relative_path":self.repodata(label)}
for label in labels]
print "Solving deps"
-
+
solver = DepSolver(repos, nvrea_list)
dep_results = solver.processResults(solver.getDependencylist())
@@ -222,13 +233,16 @@ class ChannelTreeCloner:
for dep, solved_list in pkg.items():
found = False
for cloner in self.cloners:
- if cloner.src_pkg_exist(solved_list) and not
cloner.dest_pkg_exist(solved_list):
+ exists_from = cloner.src_pkg_exist(solved_list)
+ exists_to = cloner.dest_pkg_exist(solved_list)
+ if exists_from and not exists_to:
needed_list[cloner.dest_label()].append(solved_list[0]) #grab
oldest package
- found = True
+ elif exists_from:
+ found = True
if not found:
unsolved_deps.append((pkg))
- print "Unsolved deps: %i" % len(unsolved_deps)
+ print "Unsolved deps: %i" % len(unsolved_deps)
print "Needed deps: "
for label in needed_list.keys():
print "%s: %i" % (label, len(needed_list[label]))
@@ -243,7 +257,10 @@ class ChannelTreeCloner:
def repodata(self, label):
repo_dir = "/var/cache/rhn/repodata/%s" % label
tmp_dir = tempfile.mkdtemp(suffix="clone-by-date")
- shutil.copytree(repo_dir, tmp_dir + "/repodata/")
+ try:
+ shutil.copytree(repo_dir, tmp_dir + "/repodata/")
+ except:
+ raise UserError("Could not find repodata for %s in %s" % (label,
repo_dir))
return tmp_dir
@@ -299,7 +316,7 @@ class ChannelCloner:
def process(self):
self.clone();
self.reset_new_pkgs()
- print "New packages added: %i" % len(len(self.new_pkg_hash) -
len(self.old_pkg_hash))
+ print "New packages added: %i" % (len(self.new_pkg_hash) -
len(self.old_pkg_hash))
def process_deps(self, needed_pkgs):
needed_ids = []
commit a0448d0fa7500f79b47c647539ba31068c6a1f7b
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Mon Jan 30 10:04:58 2012 -0500
errata date clone - adding sample configuration option
diff --git a/utils/spacewalk-clone-by-date b/utils/spacewalk-clone-by-date
index e44728a..3fad22a 100755
--- a/utils/spacewalk-clone-by-date
+++ b/utils/spacewalk-clone-by-date
@@ -21,6 +21,7 @@
import sys
import datetime
from optparse import OptionParser
+import simplejson as json
#try:
import cloneByDate
@@ -29,6 +30,24 @@ from cloneByDate import UserError
# from utils import cloneByDate
+SAMPLE_CONFIG = """
+{
+ "username":"admin",
+ "password":"redhat",
+ "assumeyes":true,
+ "to_date": "2011-10-01",
+ "channels":[
+ {
+ "rhel-x86_64-server-5":"my-rhel5-x86_64-clone",
+ "rhn-tools-rhel-x86_64-server-5":
"my-tools-5-x86_64-clone"
+ },
+ {
+ "rhel-i386-server-5": "my-rhel5-i386-clone"
+ }
+ ]
+}
+"""
+
def merge_config(options):
if not options.config:
@@ -38,7 +57,7 @@ def merge_config(options):
#if soemthing is in the config and not passed in as an argument
# add it to options
- overwrite = ["username", "password", "blacklist",
"channels", "server", "assumeyes"]
+ overwrite = ["username", "password", "blacklist",
"channels", "server", "assumeyes", "to_date"]
for key in overwrite:
if config.has_key(key) and not getattr(options, key):
setattr(options, key, config[key])
@@ -72,12 +91,20 @@ def parse_args():
parser.add_option("-b", "--blacklist",
dest="blacklist", nargs="*", help="Space seperated list of
package names")
parser.add_option("-d", "--to_date", dest="to_date",
help="Clone errata to the specified date (YYYY-MM-DD)")
parser.add_option("-y", "--assumeyes", dest='assumeyes',
action='store_true', help="Assume yes for any prompts (unattended).")
+ parser.add_option("-m", "--sample-config", dest='sample',
action='store_true', help="Print a sample full configuration file and
exit.")
(options, args) = parser.parse_args()
- options.to_date = parse_time(options.to_date)
+ if options.sample:
+ print SAMPLE_CONFIG
+ sys.exit(0)
+
if options.config and options.channels:
raise UserError("Cannot specify both --channels and --config.")
+
+ options = merge_config(options)
+ options.to_date = parse_time(options.to_date)
+
if options.channels == None or len(options.channels) == 0:
raise UserError("No channels specified.")
return options
@@ -104,9 +131,8 @@ def systemExit(code, msgs=None):
def main():
try:
- args = parse_args();
- options = merge_config(args)
- return cloneByDate.main(options)
+ args = parse_args();
+ return cloneByDate.main(args)
except KeyboardInterrupt:
systemExit(0, "\nUser interrupted process.")
except UserError, error: