Example #1
0
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
Example #2
0
    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)
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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")
Example #12
0
    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
Example #14
0
    def _get_runlevel(self):
        (out, stdout, stderr) = ecm.run_command(RUNLEVEL)
        if not out:
            return str(stdout).split(' ')[1].rstrip()

        return 0