summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--cobbler/action_reposync.py37
-rw-r--r--cobbler/item_repo.py18
-rw-r--r--cobbler/kickgen.py7
-rw-r--r--cobbler/modules/cli_repo.py2
-rw-r--r--cobbler/remote.py5
-rw-r--r--cobbler/services.py1
-rw-r--r--cobbler/webui/CobblerWeb.py7
-rw-r--r--docs/cobbler.pod6
-rw-r--r--webui_templates/repo_edit.tmpl30
10 files changed, 90 insertions, 24 deletions
diff --git a/CHANGELOG b/CHANGELOG
index eec038e..2a70394 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -38,6 +38,7 @@ Cobbler CHANGELOG
- xen kernel (PV) distros do not get added to PXE menus as they won't boot there
- cobbler buildiso command to build non live ISOs
- cobbler replicate command
+- added cobbler repo option --mirror-locally to reference external repos without mirroring
- ??? - 0.8.3
- Make createrepo get run for local cobbler reposync invocations as needed
diff --git a/cobbler/action_reposync.py b/cobbler/action_reposync.py
index d6b97a0..33bfe30 100644
--- a/cobbler/action_reposync.py
+++ b/cobbler/action_reposync.py
@@ -57,8 +57,10 @@ class RepoSync:
self.verbose = verbose
for repo in self.repos:
if name is not None and repo.name != name:
+ # invoked to sync only a specific repo, this is not the one
continue
elif name is None and not repo.keep_updated:
+ # invoked to run against all repos, but this one is off
print _("- %s is set to not be updated") % repo.name
continue
@@ -71,6 +73,8 @@ class RepoSync:
if repo.is_rsync_mirror():
self.do_rsync(repo)
else:
+ # which may actually NOT reposync if the repo is set to not mirror locally
+ # but that's a technicality
self.do_reposync(repo)
self.update_permissions(repo_path)
@@ -105,7 +109,7 @@ class RepoSync:
store_path = os.path.join(self.settings.webdir, "repo_mirror")
dest_path = os.path.join(store_path, repo.name)
temp_path = os.path.join(store_path, ".origin")
- if not os.path.isdir(temp_path):
+ if not os.path.isdir(temp_path) and repo.mirror_locally:
# FIXME: there's a chance this might break the RHN D/L case
os.makedirs(temp_path)
@@ -118,18 +122,21 @@ class RepoSync:
# this is the simple non-RHN case.
# create the config file that yum will use for the copying
- temp_file = self.create_local_file(repo, temp_path, output=False)
+ if repo.mirror_locally:
+ temp_file = self.create_local_file(repo, temp_path, output=False)
- if not has_rpm_list:
+ if not has_rpm_list and repo.mirror_locally:
# if we have not requested only certain RPMs, use reposync
cmd = "/usr/bin/reposync --config=%s --repoid=%s --download_path=%s" % (temp_file, repo.name, store_path)
if repo.arch != "":
+ if repo.arch == "x86":
+ repo.arch = "i386" # FIX potential arch errors
cmd = "%s -a %s" % (cmd, repo.arch)
print _("- %s") % cmd
cmds.append(cmd)
- else:
+ elif repo.mirror_locally:
# create the output directory if it doesn't exist
if not os.path.exists(dest_path):
@@ -149,6 +156,8 @@ class RepoSync:
# this is the somewhat more-complex RHN case.
# NOTE: this requires that you have entitlements for the server and you give the mirror as rhn://$channelname
+ if not repo.mirror_locally:
+ raise CX(_("rhn:// repos do not work with --mirror-locally=1"))
if has_rpm_list:
print _("- warning: --rpm-list is not supported for RHN content")
@@ -161,7 +170,6 @@ class RepoSync:
if repo.arch != "":
cmd = "%s -a %s" % (cmd, repo.arch)
- print _("- %s") % cmd
cmds.append(cmd)
# now regardless of whether we're doing yumdownloader or reposync
@@ -169,9 +177,10 @@ class RepoSync:
# commands here. Any failure at any point stops the operation.
for cmd in cmds:
- rc = sub_process.call(cmd, shell=True)
- if rc !=0:
- raise CX(_("cobbler reposync failed"))
+ if repo.mirror_locally:
+ rc = sub_process.call(cmd, shell=True)
+ if rc !=0:
+ raise CX(_("cobbler reposync failed"))
# some more special case handling for RHN.
# create the config file now, because the directory didn't exist earlier
@@ -181,7 +190,8 @@ class RepoSync:
# now run createrepo to rebuild the index
- os.path.walk(dest_path, self.createrepo_walker, repo)
+ if repo.mirror_locally:
+ os.path.walk(dest_path, self.createrepo_walker, repo)
# create the config file the hosts will use to access the repository.
@@ -196,6 +206,9 @@ class RepoSync:
Handle copying of rsync:// and rsync-over-ssh repos.
"""
+ if not repo.mirror_locally:
+ raise CX(_("rsync:// urls must be mirrored locally, yum cannot access them directly"))
+
if repo.rpm_list != "":
print _("- warning: --rpm-list is not supported for rsync'd repositories")
dest_path = os.path.join(self.settings.webdir, "repo_mirror", repo.name)
@@ -238,7 +251,11 @@ class RepoSync:
optenabled = False
optgpgcheck = False
if output:
- line = "baseurl=http://${server}/cobbler/repo_mirror/%s\n" % (repo.name)
+ if repo.mirror_locally:
+ line = "baseurl=http://${server}/cobbler/repo_mirror/%s\n" % (repo.name)
+ else:
+ line = "baseurl=%s" % (repo.mirror)
+
config_file.write(line)
# user may have options specific to certain yum plugins
# add them to the file
diff --git a/cobbler/item_repo.py b/cobbler/item_repo.py
index b87528d..ba32a07 100644
--- a/cobbler/item_repo.py
+++ b/cobbler/item_repo.py
@@ -31,6 +31,7 @@ class Repo(item.Item):
def clear(self,is_subobject=False):
self.parent = None
self.name = None
+ # FIXME: subobject code does not really make sense for repos
self.mirror = (None, '<<inherit>>')[is_subobject]
self.keep_updated = ('y', '<<inherit>>')[is_subobject]
self.priority = (99, '<<inherit>>')[is_subobject]
@@ -40,6 +41,7 @@ class Repo(item.Item):
self.arch = "" # use default arch
self.yumopts = {}
self.owners = self.settings.default_ownership
+ self.mirror_locally = 1
def from_datastruct(self,seed_data):
self.parent = self.load_item(seed_data, 'parent')
@@ -53,6 +55,7 @@ class Repo(item.Item):
self.depth = self.load_item(seed_data, 'depth', 2)
self.yumopts = self.load_item(seed_data, 'yumopts', {})
self.owners = self.load_item(seed_data, 'owners', self.settings.default_ownership)
+ self.mirror_locally = self.load_item(seed_data, 'mirror_locally', '1')
# coerce types from input file
self.set_keep_updated(self.keep_updated)
@@ -70,7 +73,7 @@ class Repo(item.Item):
if mirror.find("x86_64") != -1:
self.set_arch("x86_64")
elif mirror.find("x86") != -1 or mirror.find("i386") != -1:
- self.set_arch("x86")
+ self.set_arch("i386")
elif mirror.find("ia64") != -1:
self.set_arch("ia64")
return True
@@ -165,6 +168,7 @@ class Repo(item.Item):
'name' : self.name,
'owners' : self.owners,
'mirror' : self.mirror,
+ 'mirror_locally' : self.mirror_locally,
'keep_updated' : self.keep_updated,
'priority' : self.priority,
'rpm_list' : self.rpm_list,
@@ -175,10 +179,19 @@ class Repo(item.Item):
'yumopts' : self.yumopts
}
+ def set_mirror_locally(self,value):
+ value = str(value).lower()
+ if value in [ "yes", "y", "1", "on", "true" ]:
+ self.mirror_locally = 1
+ else:
+ self.mirror_locally = 0
+ return True
+
def printable(self):
buf = _("repo : %s\n") % self.name
buf = buf + _("owners : %s\n") % self.owners
buf = buf + _("mirror : %s\n") % self.mirror
+ buf = buf + _("mirror locally : %s\n") % self.mirror_locally
buf = buf + _("keep updated : %s\n") % self.keep_updated
buf = buf + _("priority : %s\n") % self.priority
buf = buf + _("rpm list : %s\n") % self.rpm_list
@@ -215,6 +228,7 @@ class Repo(item.Item):
'rpm-list' : self.set_rpm_list,
'createrepo-flags' : self.set_createrepo_flags,
'yumopts' : self.set_yumopts,
- 'owners' : self.set_owners
+ 'owners' : self.set_owners,
+ 'mirror-locally' : self.set_mirror_locally
}
diff --git a/cobbler/kickgen.py b/cobbler/kickgen.py
index a5e540e..a9bc095 100644
--- a/cobbler/kickgen.py
+++ b/cobbler/kickgen.py
@@ -146,13 +146,18 @@ class KickGen:
configs = self.get_repo_filenames(obj,is_profile)
repos = self.repos
+ # FIXME: this really should be dynamically generated as with the kickstarts
for c in configs:
name = c.split("/")[-1].replace(".repo","")
(is_core, baseurl) = self.analyze_repo_config(c)
for repo in repos:
if repo.name == name:
if not repo.yumopts.has_key('enabled') or repo.yumopts['enabled'] == '1':
- buf = buf + "repo --name=%s --baseurl=%s\n" % (name, baseurl)
+ if repo.mirror_locally:
+ buf = buf + "repo --name=%s --baseurl=%s\n" % (name, baseurl)
+ else:
+ buf = buf + "repo --name=%s --baseurl=%s\n" % (name, repo.mirror)
+
return buf
def analyze_repo_config(self, filename):
diff --git a/cobbler/modules/cli_repo.py b/cobbler/modules/cli_repo.py
index f31ab26..af6a9d1 100644
--- a/cobbler/modules/cli_repo.py
+++ b/cobbler/modules/cli_repo.py
@@ -51,6 +51,7 @@ class RepoFunction(commands.CobblerFunction):
if not self.matches_args(args,["dumpvars","remove","report","list"]):
p.add_option("--mirror", dest="mirror", help="source to mirror (REQUIRED)")
+ p.add_option("--mirror-locally", dest="mirror_locally", help="mirror or use external directly? (default 1)")
p.add_option("--priority", dest="priority", help="set priority")
p.add_option("--rpm-list", dest="rpm_list", help="just mirror these rpms")
p.add_option("--yumopts", dest="yumopts", help="ex: pluginvar=abcd")
@@ -81,6 +82,7 @@ class RepoFunction(commands.CobblerFunction):
if self.options.keep_updated: obj.set_keep_updated(self.options.keep_updated)
if self.options.priority: obj.set_priority(self.options.priority)
if self.options.mirror: obj.set_mirror(self.options.mirror)
+ if self.options.mirror_locally: obj.set_mirror_locally(self.options.mirror_locally)
if self.options.yumopts: obj.set_yumopts(self.options.yumopts)
if self.options.owners:
diff --git a/cobbler/remote.py b/cobbler/remote.py
index 749298e..87695d2 100644
--- a/cobbler/remote.py
+++ b/cobbler/remote.py
@@ -65,6 +65,11 @@ class CobblerXMLRPCInterface:
def ping(self):
return True
+ def update(self,token=None):
+ # ensure the config is up to date as of /now/
+ self.api.deserialize()
+ return True
+
def get_user_from_token(self,token):
if not TOKEN_CACHE.has_key(token):
raise CX(_("invalid token: %s") % token)
diff --git a/cobbler/services.py b/cobbler/services.py
index adaf6fc..1cb3864 100644
--- a/cobbler/services.py
+++ b/cobbler/services.py
@@ -45,6 +45,7 @@ class CobblerSvc(object):
This is the version that does not require logins.
"""
self.remote = xmlrpclib.Server(self.server, allow_none=True)
+ self.remote.update()
def modes(self):
"""
diff --git a/cobbler/webui/CobblerWeb.py b/cobbler/webui/CobblerWeb.py
index 2eeb1a3..0951633 100644
--- a/cobbler/webui/CobblerWeb.py
+++ b/cobbler/webui/CobblerWeb.py
@@ -61,6 +61,8 @@ class CobblerWeb(object):
try:
self.remote.token_check(self.token)
self.username = self.remote.get_user_from_token(self.token)
+ # ensure config is up2date
+ self.remote.update(self.token)
return True
except Exception, e:
if str(e).find("invalid token") != -1:
@@ -79,6 +81,8 @@ class CobblerWeb(object):
log_exc(self.apache)
return False
self.password = None # don't need it anymore, get rid of it
+ # ensure configuration is up2date
+ self.remote.update(self.token)
return True
# login failed
@@ -631,7 +635,7 @@ class CobblerWeb(object):
} )
def repo_save(self,name=None,oldname=None,new_or_edit=None,editmode="edit",
- mirror=None,owners=None,keep_updated=None,priority=99,
+ mirror=None,owners=None,keep_updated=None,mirror_locally=0,priority=99,
rpm_list=None,createrepo_flags=None,arch=None,yumopts=None,
delete1=None,delete2=None,**args):
if not self.__xmlrpc_setup():
@@ -675,6 +679,7 @@ class CobblerWeb(object):
self.remote.modify_repo(repo, 'mirror', mirror, self.token)
self.remote.modify_repo(repo, 'keep-updated', keep_updated, self.token)
self.remote.modify_repo(repo, 'priority', priority, self.token)
+ self.remote.modify_repo(repo, 'mirror-locally', mirror_locally, self.token)
if rpm_list:
self.remote.modify_repo(repo, 'rpm-list', rpm_list, self.token)
diff --git a/docs/cobbler.pod b/docs/cobbler.pod
index 018c3f4..9f5154e 100644
--- a/docs/cobbler.pod
+++ b/docs/cobbler.pod
@@ -280,7 +280,7 @@ on your network will result in faster, more up-to-date installations and faster
are only provisioning a home setup, this will probably be overkill, though it can be very useful
for larger setups (labs, datacenters, etc).
-B<cobbler repo add --mirror=url --name=string [--rpmlist=list] [--creatrepo-flags=string] [--keep-updated=Y/N] [--priority=number][--arch=string]>
+B<cobbler repo add --mirror=url --name=string [--rpmlist=list] [--creatrepo-flags=string] [--keep-updated=Y/N] [--priority=number] [--arch=string] [--mirror-locally=Y/N]>
=over
@@ -335,6 +335,10 @@ Specifies optional flags to feed into the createrepo tool, which is called when
Specifies that the named repository should not be updated during a normal "cobbler reposync". The repo may still be updated by name. See "cobbler reposync" below.
+=item mirror-locally
+
+When true, specifies that this yum repo is to be referenced directly via kickstarts and not mirrored locally on the cobbler server. Only http:// and ftp:// mirror urls are supported when using --mirror-locally=1.
+
=item priority
Specifies the priority of the repository (the lower the number, the higher the priority), which applies to installed machines using the repositories that also have the yum priorities plugin installed. The default priority for the plugin is 99, as is that of all cobbler mirrored repositories.
diff --git a/webui_templates/repo_edit.tmpl b/webui_templates/repo_edit.tmpl
index 30d516d..c259a13 100644
--- a/webui_templates/repo_edit.tmpl
+++ b/webui_templates/repo_edit.tmpl
@@ -90,10 +90,24 @@ function disablename(value)
checked="true"
#end if
/>
- <p class="context-tip">Disable to prevent the mirror from being updated.</p>
+ <p class="context-tip">Uncheck to prevent the mirror from being updated again.</p>
</td>
</tr>
+ <br/>
+ <tr>
+ <td>
+ <label for="keep_updated">Mirror Locally</label>
+ </td>
+ <td>
+ <input type="checkbox" name="mirror_locally" id="mirror_locally"
+ #if (not $repo) or $repo.mirror_locally
+ checked="true"
+ #end if
+ />
+ <p class="context-tip">Uncheck to reference the repository directly instead of mirroring.</p>
+ </td>
+ </tr>
<br/>
<tr>
@@ -130,7 +144,7 @@ function disablename(value)
<tr>
<td>
- <label for="createrepo_flags">createrepo flags</label>
+ <label for="createrepo_flags">Createrepo flags</label>
</td>
<td>
<input type="text" size="255" style="width: 150px;" name="creatrepoflags" id="createrepoflags"
@@ -144,7 +158,7 @@ function disablename(value)
<tr>
<td>
- <label for="arch">arch</label>
+ <label for="arch">Arch</label>
</td>
<td>
<input type="text" size="255" style="width: 150px;" name="arch" id="arch"
@@ -158,7 +172,7 @@ function disablename(value)
<tr>
<td>
- <label for="yumopts">yum options</label>
+ <label for="yumopts">Yum options</label>
</td>
<td>
<input type="text" size="255" style="width: 150px;" name="yumopts" id="yumopts"
@@ -219,11 +233,9 @@ function disablename(value)
<br/>
<blockquote>
-Note: Newly added repos contain no package content until
-"cobbler reposync" is run from the command line, which means
-that profiles relying on these repositories will not install.
-Placing "cobbler reposync" on a crontab to ensure frequent
-updates is recommended procedure.
+Note: Newly added repo definitions will not be usable until
+"cobbler reposync" is run from the command line on this system.
+Placing "cobbler reposync" on a crontab is recommended procedure.
</blockquote>
<br/>