summaryrefslogtreecommitdiffstats
path: root/cobbler
diff options
context:
space:
mode:
Diffstat (limited to 'cobbler')
-rw-r--r--cobbler/action_hardlink.py56
-rw-r--r--cobbler/action_sync.py3
-rw-r--r--cobbler/api.py5
-rw-r--r--cobbler/collection.py1
-rw-r--r--cobbler/collection_distros.py2
-rw-r--r--cobbler/collection_images.py2
-rw-r--r--cobbler/collection_profiles.py2
-rw-r--r--cobbler/collection_repos.py4
-rw-r--r--cobbler/collection_systems.py2
-rw-r--r--cobbler/modules/cli_misc.py17
-rw-r--r--cobbler/modules/scm_track.py62
-rw-r--r--cobbler/remote.py11
-rw-r--r--cobbler/settings.py2
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",