diff options
Diffstat (limited to 'cobbler')
-rw-r--r-- | cobbler/action_hardlink.py | 56 | ||||
-rw-r--r-- | cobbler/action_sync.py | 3 | ||||
-rw-r--r-- | cobbler/api.py | 5 | ||||
-rw-r--r-- | cobbler/collection.py | 1 | ||||
-rw-r--r-- | cobbler/collection_distros.py | 2 | ||||
-rw-r--r-- | cobbler/collection_images.py | 2 | ||||
-rw-r--r-- | cobbler/collection_profiles.py | 2 | ||||
-rw-r--r-- | cobbler/collection_repos.py | 4 | ||||
-rw-r--r-- | cobbler/collection_systems.py | 2 | ||||
-rw-r--r-- | cobbler/modules/cli_misc.py | 17 | ||||
-rw-r--r-- | cobbler/modules/scm_track.py | 62 | ||||
-rw-r--r-- | cobbler/remote.py | 11 | ||||
-rw-r--r-- | cobbler/settings.py | 2 |
13 files changed, 167 insertions, 2 deletions
diff --git a/cobbler/action_hardlink.py b/cobbler/action_hardlink.py new file mode 100644 index 00000000..6e17e357 --- /dev/null +++ b/cobbler/action_hardlink.py @@ -0,0 +1,56 @@ +""" +Hard links cobbler content together to save space. + +Copyright 2009, Red Hat, Inc +Michael DeHaan <mdehaan@redhat.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA +""" + +import os +import utils +from cexceptions import * + +class HardLinker: + + def __init__(self,config): + """ + Constructor + """ + #self.config = config + #self.api = config.api + #self.settings = config.settings() + pass + + def run(self): + """ + Simply hardlinks directories that are cobbler managed. + This is a /very/ simple command but may grow more complex + and intelligent over time. + """ + + # FIXME: if these directories become configurable some + # changes will be required here. + + if not os.path.exists("/usr/sbin/hardlink"): + raise CX("please install 'hardlink' (/usr/sbin/hardlink) to use this feature") + + print "now hardlinking to save space, this may take some time." + + rc = os.system("/usr/sbin/hardlink -c -v /var/www/cobbler/ks_mirror /var/www/cobbler/repo_mirror") + + return rc + diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index 78f3c3d5..76211418 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -141,7 +141,10 @@ class BootSync: # run post-triggers if self.verbose: print "- running post-sync triggers" + utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/sync/post/*") + utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/change/*") + return True def clean_trees(self): diff --git a/cobbler/api.py b/cobbler/api.py index ffc62644..c36d442a 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -36,6 +36,7 @@ import action_replicate import action_acl import action_report import action_power +import action_hardlink from cexceptions import * import sub_process import module_loader @@ -681,6 +682,10 @@ class BootAPI: iso=iso, profiles=profiles, systems=systems, tempdir=tempdir, distro=distro, standalone=standalone, source=source ) + def hardlink(self): + linker = action_hardlink.HardLinker(self._config) + return linker.run() + def replicate(self, cobbler_master = None, sync_all=False, sync_kickstarts=False, sync_trees=False, sync_repos=False, sync_triggers=False, systems=False): """ Pull down metadata from a remote cobbler server that is a master to this server. diff --git a/cobbler/collection.py b/cobbler/collection.py index 3bc15cc7..50c07094 100644 --- a/cobbler/collection.py +++ b/cobbler/collection.py @@ -284,6 +284,7 @@ class Collection(serializable.Serializable): # save the tree, so if neccessary, scripts can examine it. if with_triggers: + self._run_triggers(self.api, ref, "/var/lib/cobbler/triggers/change/*") self._run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/post/*" % self.collection_type()) diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py index ae75f407..bcb23a07 100644 --- a/cobbler/collection_distros.py +++ b/cobbler/collection_distros.py @@ -76,6 +76,8 @@ class Distros(collection.Collection): self.log_func("deleted distro %s" % name) if with_triggers: self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/post/*") + self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + # look through all mirrored directories and find if any directory is holding # this particular distribution's kernel and initrd diff --git a/cobbler/collection_images.py b/cobbler/collection_images.py index 2dfeeac1..1bf52069 100644 --- a/cobbler/collection_images.py +++ b/cobbler/collection_images.py @@ -69,6 +69,8 @@ class Images(collection.Collection): self.log_func("deleted repo %s" % name) if with_triggers: self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/post/*") + self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + return True if with_delete and not self.api.is_cobblerd: diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py index bb27dea4..5ca9d4be 100644 --- a/cobbler/collection_profiles.py +++ b/cobbler/collection_profiles.py @@ -74,6 +74,8 @@ class Profiles(collection.Collection): self.log_func("deleted profile %s" % name) if with_triggers: self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/post/*") + self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + if with_delete and not self.api.is_cobblerd: self.api._internal_cache_update("profile", name, remove=True) diff --git a/cobbler/collection_repos.py b/cobbler/collection_repos.py index 3b2c1c20..eef82b8c 100644 --- a/cobbler/collection_repos.py +++ b/cobbler/collection_repos.py @@ -65,7 +65,9 @@ class Repos(collection.Collection): self.log_func("deleted repo %s" % name) if with_triggers: self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/post/*") - + self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + + path = "/var/www/cobbler/repo_mirror/%s" % obj.name if os.path.exists(path): utils.rmtree(path) diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py index 5a628248..16576802 100644 --- a/cobbler/collection_systems.py +++ b/cobbler/collection_systems.py @@ -62,7 +62,9 @@ class Systems(collection.Collection): self.log_func("deleted system %s" % name) if with_triggers: self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/post/*") + self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + if with_delete and not self.api.is_cobblerd: self.api._internal_cache_update("system", name, remove=True) diff --git a/cobbler/modules/cli_misc.py b/cobbler/modules/cli_misc.py index f83b5c8c..a4fc4708 100644 --- a/cobbler/modules/cli_misc.py +++ b/cobbler/modules/cli_misc.py @@ -39,6 +39,21 @@ HELP_FORMAT = commands.HELP_FORMAT ######################################################## +class HardLinkFunction(commands.CobblerFunction): + def help_me(self): + return HELP_FORMAT % ("cobbler hardlink","") + + def command_name(self): + return "hardlink" + + def add_options(self, p, args): + pass + + def run(self): + self.api.hardlink() + +######################################################## + class CheckFunction(commands.CobblerFunction): def help_me(self): @@ -359,7 +374,7 @@ def cli_functions(api): ListFunction(api), StatusFunction(api), SyncFunction(api), RepoSyncFunction(api), ValidateKsFunction(api), ReplicateFunction(api), AclFunction(api), - VersionFunction(api) + VersionFunction(api), HardLinkFunction(api) ] return [] diff --git a/cobbler/modules/scm_track.py b/cobbler/modules/scm_track.py new file mode 100644 index 00000000..dd9ef687 --- /dev/null +++ b/cobbler/modules/scm_track.py @@ -0,0 +1,62 @@ +import distutils.sysconfig +import sys +import os +import traceback +from cobbler.cexceptions import * +import os +import sub_process +import sys +#import xmlrpclib +import cobbler.module_loader as module_loader + +plib = distutils.sysconfig.get_python_lib() +mod_path="%s/cobbler" % plib +sys.path.insert(0, mod_path) + +def register(): + # this pure python trigger acts as if it were a legacy shell-trigger, but is much faster. + # the return of this method indicates the trigger type + return "/var/lib/cobbler/triggers/change/*" + +def scall(args): + op = sub_process.Popen(args, shell=False, stdout=sub_process.PIPE, stderr=sub_process.PIPE) + op.communicate() + + +def run(api,args): + + + settings = api.settings() + + scm_track_enabled = str(settings.scm_track_enabled).lower() + mode = str(settings.scm_track_mode).lower() + + if scm_track_enabled not in [ "y", "yes", "1", "true" ]: + # feature disabled + return 0 + + if mode == "git": + + old_dir = os.getcwd() + os.chdir("/var/lib/cobbler") + if os.getcwd() != "/var/lib/cobbler": + raise "danger will robinson" + + if not os.path.exists("/var/lib/cobbler/.git"): + scall(["git","init"]) + + # FIXME: if we know the remote user of an XMLRPC call + # use them as the author + + scall(["git","add","config"]) + scall(["git","add","kickstarts"]) + scall(["git","add","snippets"]) + + scall(["git","commit","-m",'API update',"--author","'cobbler <root@localhost.localdomain>'"]) + + os.chdir(old_dir) + + return 0 + + else: + raise CX("currently unsupported SCM type: %s" % mode) diff --git a/cobbler/remote.py b/cobbler/remote.py index 6fdb96fe..eaf3d41d 100644 --- a/cobbler/remote.py +++ b/cobbler/remote.py @@ -1138,6 +1138,17 @@ class CobblerXMLRPCInterface: self.check_access(token,"sync") return self.api.sync() + def hardlink(self,token): + """ + Hardlink trees and repos to save disk space. Caution: long + running op. Until we have a task engine, this may lock other + folks out of the web app, so use wisely. It may also be timeout + prone. + """ + self._log("hardlink",token=token) + self.check_access(token,"hardlink") + return self.api.hardlink() + def new_distro(self,token): """ Creates a new (unconfigured) distro object. It works something like diff --git a/cobbler/settings.py b/cobbler/settings.py index bf94d24d..2422341a 100644 --- a/cobbler/settings.py +++ b/cobbler/settings.py @@ -105,6 +105,8 @@ DEFAULTS = { "ris_linuxd_dir" : "/tftpboot/drivers", "ris_linuxd_flags" : "", "run_install_triggers" : 1, + "scm_track_enabled" : 0, + "scm_track_mode" : "git", "server" : "127.0.0.1", "snippetsdir" : "/var/lib/cobbler/snippets", "tftpd_bin" : "/usr/sbin/in.tftpd", |