def _run_background_file(script, run_as=None): fullpath = os.path.abspath(script) script_name = os.path.basename(fullpath) workdir = os.path.dirname(script) # Create child process and return if parent if ecm.fork(workdir): return # Write timeout to cache file _write_cache(script_name, CRITICAL, 'Timeout') try: command = [fullpath] sys.path.append(MY_PATH) env = os.environ.copy() env['PYTHONPATH'] = MY_PATH + ':' + env.get('PYTHONPATH', '') retval, stdout, stderr = ecm.run_command(command, runas=run_as, envars=env) _write_cache(script_name, retval, stdout) except Exception, e: _write_cache(script_name, CRITICAL, e.message) pass
def _run_puppet(self, recipe_file, recipe_path, module_path, catalog_cmd='catalog', envars=None): """ Real puppet execution """ puppet_cmd = self._is_available() if not puppet_cmd: raise Exception("Puppet is not available") command = [puppet_cmd, 'apply', '--detailed-exitcodes', '--modulepath', module_path, '--debug', '--' + catalog_cmd, recipe_file] out, std_out, std_err = ecm.run_command(command, workdir=recipe_path, envars=envars) ret = ecm.format_output(out, std_out, std_err) # --detailed-exitcodes # Provide transaction information via exit codes. If this is enabled, # an exit code of '2' means there were changes, # an exit code of '4' means there were failures during the transaction, # and an exit code of '6' means there were both changes and failures. # bug in exitcodes in some version even with errors return 0 # http://projects.puppetlabs.com/issues/6322 if ret['out'] == 2: ret['out'] = 0 if "\nError: " in ret['stderr']: ret['out'] = 4 return ret
def clone(self, url, branch, envars, username, password, private_key): """ runs git clone URL """ command = self._get_command(url,branch) # Create git command with user and password if username and password: parsed = urlparse(url) if parsed.scheme in ('http', 'https'): command = command.replace('://', '://' + username + ':' + password + '@') elif parsed.scheme == 'ssh': command = command.replace('://', '://' + username + '@') elif private_key: helper, indetity = self._certificate_helper(private_key) envars['GIT_SSH'] = helper out, stdout, stderr = ecm.run_command(command=command, workdir=self.working_dir, envars=envars) result_exec = ecm.format_output(out, stdout, stderr) if not result_exec['out']: extra_msg = ecm.output("Source deployed successfully to '%s'" % self.working_dir) if self.old_dir: extra_msg += ecm.output("Old source files moved to '%s'" % self.old_dir) result_exec['stdout'] += extra_msg if private_key: try: os.unlink(helper) os.unlink(indetity) except: pass return result_exec
def cmd_saltstack_apply(self, *argv, **kwargs): """ Apply a saltstack manifest Syntax: saltstack.apply[recipe_code,pillar_code,envars,facts] """ recipe_base64 = kwargs.get('recipe_code', None) pillar_base64 = kwargs.get('pillar_code', None) recipe_envars = kwargs.get('envars', None) recipe_facts = kwargs.get('facts', None) if not recipe_base64: raise ecm.InvalidParameters(self.cmd_saltstack_apply.__doc__) saltstack_cmd = self._is_available() if not saltstack_cmd: raise Exception('Saltstack no available') # Get default paths default_path = DEFAULT_SALT_PATH if ecm.is_windows(): default_path = DEFAULT_SALT_PATH_WINDOWS module_path = kwargs.get('module_path', default_path) default_pillar_path = DEFAULT_PILLAR_PATH if ecm.is_windows(): default_pillar_path = DEFAULT_PILLAR_PATH_WINDOWS pillar_path = kwargs.get('pillar_path', default_pillar_path) # Set environment variables before execution envars = ecm.envars_decode(recipe_envars) facts = ecm.envars_decode(recipe_facts) # Update envars and facts file ecm.write_envars_facts(envars, facts) try: # Create top file self._create_top_file(module_path) recipe_file = module_path + '/ecmanaged.sls' ecm.file_write(recipe_file, b64decode(recipe_base64)) if pillar_base64: self._create_top_file(pillar_path) pillar_file = pillar_path + '/ecmanaged.sls' ecm.file_write(pillar_file, b64decode(pillar_base64)) except: raise Exception("Unable to write recipe") try: # salt-call state.highstate command = [saltstack_cmd, 'state.highstate', '--local', '--no-color', '-l debug'] out, stdout, stderr = ecm.run_command(command, envars=envars, workdir=module_path) return ecm.format_output(out, stdout, stderr) except Exception as e: raise Exception("Error running saltstack state.highstate: %s" % e)
def cmd_service_state(self, *argv, **kwargs): """Syntax: service.exists daemon""" name = kwargs.get('name', None) if not name: raise ecm.InvalidParameters(self.cmd_service_state.__doc__) daemon = os.path.basename(name) out, stdout, stderr = ecm.run_command(INITD + '/' + daemon + ' status') return not bool(out)
def cmd_configfile_run(self, *argv, **kwargs): """ Deploy a file Syntax: configfile.run[configfile,file,chown_user,chown_group,chmod,rotate,command,runas] """ code_base64 = kwargs.get('configfile', None) filename = kwargs.get('path', None) chown_user = kwargs.get('chown_user', None) chown_group = kwargs.get('chown_group', None) chmod = kwargs.get('chmod', None) rotate = kwargs.get('rotate', False) command = kwargs.get('command', None) runas = kwargs.get('command_runas', None) if not code_base64 or not filename: raise ecm.InvalidParameters(self.cmd_configfile_run.__doc__) ret = {'out': 0,'stdout': '','stderr': ''} try: if rotate and os.path.isfile(filename): new_file = filename + '_rotated_' + ecm.utime() move(filename, new_file) ret['stdout'] = ecm.output("Old configfile moved to '%s'" % new_file) # Write down file ecm.file_write(filename, b64decode(code_base64)) ret['stdout'] += ecm.output("Configfile created successfully at '%s'" % filename) except Exception as e: raise Exception("Unable to write configfile: %s" % e) try: # Chown to specified user/group if chown_user and chown_group and os.path.isfile(filename): ecm.chown(filename, chown_user, chown_group) ret['stdout'] += ecm.output("Owner changed to '%s':'%s'" % (chown_user, chown_group)) # Chown to specified user/group if chmod and os.path.isfile(filename): ecm.chmod(filename, chmod) ret['stdout'] += ecm.output("Owner changed to '%s':'%s'" % (chown_user, chown_group)) except Exception as e: raise Exception("Unable to change permissions for configfile: %s" % e) if command: working_dir = os.path.dirname(filename) out, stdout, stderr = ecm.run_command(command, runas=runas, workdir=working_dir) ret = ecm.format_output(out, stdout, stderr) return ret
def cmd_command_run(self, *argv, **kwargs): """ Syntax: command.run[command,args] """ command = kwargs.get('command', None) params = kwargs.get('params', None) if not command: raise ecm.InvalidParameters(self.cmd_command_run.__doc__) if command not in self.commands.keys(): raise Exception("Command %s is not available" % command) return ecm.run_command(self.commands[command], params)
def cmd_puppet_apply(self, *argv, **kwargs): """ Syntax: puppet.appy[recipe_code,evars,facts] """ recipe_base64 = kwargs.get('recipe_code', None) envars = kwargs.get('envars', None) facts = kwargs.get('facts', None) if not recipe_base64: raise ecm.InvalidParameters(self.cmd_puppet_apply.__doc__) # Set module path module_path = kwargs.get('module_path', None) if module_path is None: module_path = MODULES_PATH if ecm.is_windows(): module_path = MODULES_PATH_WINDOWS # Set environment variables before execution envars = ecm.envars_decode(envars) facts = ecm.envars_decode(facts) # Set environment variables before execution ecm.write_envars_facts(envars, facts) try: catalog = b64decode(recipe_base64) except: raise ecm.InvalidParameters("Unable to decode recipe") try: command = ['puppet', 'apply', '--modulepath', module_path, '--detailed-exitcodes', '--debug'] out, stdout, stderr = ecm.run_command(command, stdin=catalog, envars=envars) ret = ecm.format_output(out, stdout, stderr) # exit code of '2' means there were changes if ret['out'] == 2: ret['out'] = 0 if "\nError: " in ret['stderr']: ret['out'] = 4 return ret except Exception as e: raise Exception("Error running puppet apply: %s" % e)
def cmd_code_run(self, *argv, **kwargs): """ run code(b64) in path Syntax: code.run[code,path,runas] """ code_b64 = kwargs.get('code', None) code_path = kwargs.get('path', None) code_runas = kwargs.get('runas', None) if not code_b64: raise ecm.InvalidParameters(self.cmd_code_run.__doc__) try: code = b64decode(code_b64) except: raise ecm.InvalidParameters("Unable to decode b64") out, stdout, stderr = ecm.run_command(code, runas=code_runas, workdir=code_path, only_stdout=True) return ecm.format_output(out, stdout, stderr)
def cmd_script_run(self, *argv, **kwargs): """ run script(b64) extension envars runas executable Syntax: script.run[script,extenion,envars,facts,runas,executable] """ script_b64 = kwargs.get('script', None) script_extension = kwargs.get('extension', None) script_runas = kwargs.get('runas', None) script_executable = kwargs.get('executable', None) metadata = kwargs.get('metadata', None) if not script_extension: script_extension = '.cmd' if not script_b64: raise ecm.InvalidParameters(self.cmd_script_run.__doc__) try: # Write down tmp_dir = mkdtemp() tmp_file = tmp_dir + '/script' + script_extension ecm.file_write(tmp_file, b64decode(script_b64)) except: raise ecm.InvalidParameters("Unable to decode b64") # Set environment variables before execution envars = ecm.metadata_to_env(metadata_b64=metadata) # Update metadata ecm.write_metadata(metadata_b64=metadata) # Chown if script_runas: ecm.chown(tmp_dir,script_runas,recursive=True) if script_executable: cmd = script_executable + ' ' + tmp_file out, stdout, stderr = ecm.run_command(cmd, runas=script_runas, workdir=tmp_dir, envars=envars) else: out, stdout, stderr = ecm.run_file(tmp_file, runas=script_runas, workdir=tmp_dir, envars=envars) rmtree(tmp_dir, ignore_errors=True) return ecm.format_output(out, stdout, stderr)
def _extract_alternative(self, filename): """ extractor helper: Try to extract file using system commands """ from shutil import move from os import path file_type = self._get_file_type(filename) # Move file before decompress move(filename, self.working_dir) filename = path.join(self.working_dir, path.basename(filename)) if file_type == 'zip': package = 'unzip' command = 'unzip' args = [filename] elif file_type == 'gz': package = 'gzip' command = 'gunzip' args = [filename] elif file_type == 'bz2': package = 'bzip2' command = 'bzip2' args = ['-d', filename] else: raise Exception("Unsupported file compression") exists = ecm.which(command) if not exists: # Try to install package ecm.install_package(package) exists = ecm.which(command) if exists and command: # Decompress out, stdout, stderr = ecm.run_command(command, args, workdir=self.working_dir) ret = {'out': out, 'stderr': stderr, 'stdout': stdout} return ret raise Exception("Could not extract file")
def cmd_service_control(self, *argv, **kwargs): """Syntax: service.control daemon action <force: 0/1>""" daemon = kwargs.get('daemon', None) action = kwargs.get('action', None) force = kwargs.get('force', 0) if not (daemon and action): raise ecm.InvalidParameters(self.cmd_service_control.__doc__) if not force: # try to get init.d daemon initd = self._get_rcd(daemon) if not initd: raise Exception("Unable to find daemon: %s" % daemon) daemon = initd daemon = os.path.basename(daemon) ecm.renice_me(-19) out, stdout, stderr = ecm.run_command(INITD + '/' + daemon + ' ' + action) ecm.renice_me(5) return ecm.format_output(out, stdout, stderr)
def clone(self, url, branch, envars, username, password, private_key): """ svn co URL """ # Add username and password to url if username and password: url = url.replace('://', '://' + username + ':' + password + '@') command = self.svn_cmd + " co '" + url + "' ." out, stdout, stderr = ecm.run_command(command=command, workdir=self.working_dir, envars=envars) result_exec = ecm.format_output(out, stdout, stderr) if not result_exec['out']: extra_msg = ecm.output("Source deployed successfully to '%s'" % self.working_dir) if self.old_dir: extra_msg += ecm.output("Old source files moved to '%s'" % self.old_dir) if result_exec['stdout']: result_exec['stdout'] = extra_msg + result_exec['stdout'] else: result_exec['stdout'] = extra_msg return result_exec
def _get_runlevel(self): (out, stdout, stderr) = ecm.run_command(RUNLEVEL) if not out: return str(stdout).split(' ')[1].rstrip() return 0