def action_create(self): if not self.user: command = ['useradd', "-m"] options = dict( comment = "-c", gid = "-g", uid = "-u", shell = "-s", password = "******", home = "-d", ) if self.resource.system: command.append("--system") if self.resource.groups: command += ["-G", ",".join(self.resource.groups)] for option_name, option_flag in options.items(): option_value = getattr(self.resource, option_name) if option_flag and option_value: command += [option_flag, str(option_value)] command.append(self.resource.username) subprocess.check_call(command) self.resource.updated() utils.log("Added user %s" % self.resource)
def action_create(self): path = self.resource.path write = False content = self._getContent() if not os.path.exists(path): write = True reason = "it doesn't exist" else: if content is not None: with open(path, "rb") as fp: old_content = fp.read() if content != old_content: write = True reason = "contents don't match" self.resource.env.backup_file(path) if write: utils.log("Writing %s because %s" % (self.resource, reason)) with open(path, "wb") as fp: if content: fp.write(content) self.resource.updated() if _ensureMetadata(self.resource.path, self.resource.owner, self.resource.group, mode = self.resource.mode): self.resource.updated()
def action_delete(self): path = self.resource.path if os.path.exists(path): utils.log("Deleting %s" % self.resource) os.unlink(path) self.resource.updated()
def action_umount(self): if self._isMounted(): check_call(["umount", self.resource.mountPoint]) utils.log("%s unmounted" % self) self.resource.updated() else: utils.log("%s is not mounted" % self)
def action_delete(self): path = self.resource.path if os.path.exists(path): utils.log("Removing directory %s" % self.resource) os.rmdir(path) # TODO: recursive self.resource.updated()
def action_upgrade(self): if self.currentVersion != self.candidateVersion: origVersion = self.currentVersion or "uninstalled" log("Upgrading %s from version %s to %s" % (str(self.resource), origVersion, self.candidateVersion)) status = self._upgrade(self.resource.name, self.candidateVersion) if status: self.resource.updated()
def _shell(self, cmd): log(cmd) try: return shell3(cmd) except Exception: log("error executing command: %s" % cmd) raise
def action_create(self): virtualenv.create_environment(home_dir=self.resource.path, site_packages=self.resource.site_packages, clear=self.resource.clear, unzip_setuptools=self.resource.unzip_setuptools, use_distribute=self.resource.use_distribute, never_download=self.resource.never_download) log("Installed virtualenv '%s'" % self.resource.path)
def candidateVersion(self): proc = Popen([self._binaryPath, "-n", self.resource.name], stdout=PIPE, stderr=STDOUT) out = proc.communicate()[0] res = proc.wait() if res != 0: log("easy_install check returned a non-zero result (%d) %s" % (res, self.resource)) match = BEST_MATCH_RE.search(out) if not match: return None else: return match.group(2)
def action_run(self): if self.resource.creates: if os.path.exists(self.resource.creates): return utils.log("Executing %s" % self.resource) ret = utils.shell3(self.resource.path)[1] # TODO: use cwd and env # subprocess.call(self.resource.path, shell=True, cwd=self.resource.cwd, env=self.resource.env) #, preexec_fn=_preexec_fn(self.resource)) if self.resource.returns and ret not in self.resource.returns: raise Fail("%s failed, returned %d instead of %s" % (self, ret, self.resource.returns)) self.resource.updated()
def action_create(self): path = self.resource.path if not os.path.exists(path): utils.log("Creating directory %s" % self.resource) if self.resource.recursive: os.makedirs(path, self.resource.mode or 0755) else: os.mkdir(path, self.resource.mode or 0755) self.resource.updated() if _ensureMetadata(path, self.resource.owner, self.resource.group, mode = self.resource.mode): self.resource.updated()
def _install(self): # TODO: support installing ruby as a prerequisite to homebrew... brewInstalled = (0 == shell('brew --help')[1]) if brewInstalled: return else: log("installing homebrew...") # attempt to install homebrew p = Popen('ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"', shell=True) status = p.wait() if 0 != status: raise Fail("error installing homebrew")
def action_run(self): from tempfile import NamedTemporaryFile utils.log("Running script '%s'" % self.resource) utils.log("%s" % self.resource.code) with NamedTemporaryFile(prefix="pynode-script", bufsize=0) as tf: tf.write(self.resource.code) tf.flush() _ensureMetadata(tf.name, self.resource.user, self.resource.group) subprocess.call([self.resource.interpreter, tf.name], cwd=self.resource.cwd, env=self.resource.environment) #preexec_fn=_preexec_fn(self.resource)) self.resource.updated()
def candidateVersion(self): if not self.resource.version and re.match("^[A-Za-z0-9_.-]+$", self.resource.name): p = Popen([self.easy_install_binary_path, "-n", self.resource.name], stdout=PIPE, stderr=STDOUT) out = p.communicate()[0] res = p.wait() if res != 0: log("easy_install check returned a non-zero result (%d) %s" % (res, self.resource)) m = best_match_re.search(out) if not m: return None else: return m.group(2) else: return self.resource.version
def _getContent(self): content = self.resource.content if content is None: try: from pynode.source import Template as _template template = _template("mongodb/mongodb.conf.j2", dict(mongodb=self.resource)) except: utils.log("Template is f****d") raise return template() elif isinstance(content, basestring): return content elif hasattr(content, "__call__"): return content() raise Fail("Unknown source type for %s: %r" % (self, content))
def _updateCurrentStatus(self): self.currentVersion = None self.candidateVersion = None proc = Popen("apt-cache policy %s" % self.resource.name, shell=True, stdout=PIPE) out = proc.communicate()[0] for line in out.split("\n"): line = line.strip().split(':', 1) if len(line) != 2: continue ver = line[1].strip() if line[0] == "Installed": self.currentVersion = None if ver == '(none)' else ver utils.log("Current version of package %s is %s" % (self.resource.name, self.currentVersion)) elif line[0] == "Candidate": self.candidateVersion = ver if self.candidateVersion == "(none)": raise Fail("APT does not provide a version of package %s" % self.resource.name)
def action_mount(self): if not os.path.exists(self.resource.mountPoint): os.makedirs(self.resource.mountPoint) if self._isMounted(): utils.log("%s already mounted" % self) else: args = ["mount"] if self.resource.fstype: args += ["-t", self.resource.fstype] if self.resource.options: args += ["-o", ",".join(self.resource.options)] if self.resource.device: args.append(self.resource.device) args.append(self.resource.mountPoint) check_call(args) utils.log("%s mounted" % self) self.resource.updated()
def _ensureMetadata(path, user, group, mode = None): stat = os.stat(path) updated = False if mode: existingMode = stat.st_mode & 07777 if existingMode != mode: utils.log("Changing permission for %s from %o to %o" % (path, existingMode, mode)) os.chmod(path, mode) updated = True if user: uid = _coerce_uid(user) if stat.st_uid != uid: utils.log("Changing owner for %s from %d to %s" % (path, stat.st_uid, user)) os.chown(path, uid, -1) updated = True if group: gid = _coerce_gid(group) if stat.st_gid != gid: utils.log("Changing group for %s from %d to %s" % (path, stat.st_gid, group)) os.chown(path, -1, gid) updated = True return updated
def action_enable(self): if self._isEnabled(): utils.log("%s already enabled" % self) else: if not self.resource.device: raise Fail("[%s] device not set but required for enable action" % self) if not self.resource.fstype: raise Fail("[%s] fstype not set but required for enable action" % self) with open("/etc/fstab", "a") as fp: fp.write("%s %s %s %s %d %d\n" % ( self.resource.device, self.resource.mountPoint, self.resource.fstype, ",".join(self.resource.options or ["defaults"]), self.resource.dump, self.resource.passno, )) utils.log("%s enabled" % self) self.resource.updated()
def action_create(self): group = self.group if not group: command = ['groupadd'] options = dict( gid = "-g", password = "******", ) for option_name, option_flag in options.items(): option_value = getattr(self.resource, option_name) if option_flag and option_value: command += [option_flag, str(option_value)] command.append(self.resource.name) subprocess.check_call(command) self.resource.updated() utils.log("Added group %s" % self.resource) group = self.group
def _exec_cmd(self, cmd, expect=None): if cmd != "status": utils.log("%s command '%s'" % (self.resource, cmd)) custom_cmd = getattr(self.resource, "%s_cmd" % cmd, None) if custom_cmd: utils.log("%s executing '%s'" % (self.resource, custom_cmd)) if hasattr(custom_cmd, "__call__"): if custom_cmd(): ret = 0 else: ret = 1 else: print custom_cmd ret = utils.shell3(custom_cmd)[1] # subprocess.call(custom_cmd, shell=True)#, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) else: ret = self._init_cmd(cmd) if expect is not None and expect != ret: raise Fail("%r command %s for service %s failed" % (self, cmd, self.resource.name)) return ret
def action_install(self): if self.resource.version != None and self.resource.version != self.currentVersion: installVersion = self.resource.version elif self.currentVersion is None: installVersion = self.candidateVersion else: return if not installVersion: log("No version specified, and no candidate version available for resource %s." % str(self.resource)) # raise Fail("No version specified, and no candidate version available.") log("Install %s version %s" % (self.resource.name, installVersion)) log("(current: %s, candidate: %s)" % (self.currentVersion, self.candidateVersion)) status = self._install_package(self.resource.name, installVersion) if status: self.resource.updated()
def action_create(self): path = self.resource.path if os.path.lexists(path): oldpath = os.path.realpath(path) if oldpath == self.resource.to: return if not os.path.islink(path): raise Fail("%s trying to create a symlink with the same name as an existing file or directory" % self) utils.log("%s replacing old symlink to %s" % (self, oldpath)) os.unlink(path) if self.resource.hard: utils.log("Creating hard %s" % self.resource) os.link(self.resource.to, path) self.resource.updated() else: utils.log("Creating symbolic %s" % self.resource) os.symlink(self.resource.to, path) self.resource.updated()
def action_remove(self): if self.user: command = ['groupdel', self.resource.name] subprocess.check_call(command) self.resource.updated() utils.log("Removed group %s" % self.resource)
__author__ = "Stamped ([email protected])" __version__ = "1.0" __copyright__ = "Copyright (c) 2011 Stamped.com" __license__ = "TODO" __all__ = [ "VirtualEnvProvider" ] from pynode.utils import log, shell from pynode.errors import Fail from pynode.provider import Provider try: import virtualenv except ImportError as e: log("Error: must install virtualenv before using VirtualEnvProvider") raise e class VirtualEnvProvider(Provider): def action_create(self): virtualenv.create_environment(home_dir=self.resource.path, site_packages=self.resource.site_packages, clear=self.resource.clear, unzip_setuptools=self.resource.unzip_setuptools, use_distribute=self.resource.use_distribute, never_download=self.resource.never_download) log("Installed virtualenv '%s'" % self.resource.path) def action_activate(self): (output, status) = shell('. %s/bin/activate' % self.resource.path)
def action_remove(self): if self.currentVersion: log("Remove %s version %s" % (self.resource.name, self.currentVersion)) self._remove_package(self.resource.name) self.resource.updated()