コード例 #1
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def call_process(self, cmd):
        if not isinstance(cmd, list):
            exceptionhandler('Command is not a list.\n{0}'.format(str(cmd)))
        rsp = subprocess.call(cmd)

        if rsp != 0:
            exceptionhandler('Command failed.\n{0}'.format(str(cmd)))
コード例 #2
0
ファイル: __init__.py プロジェクト: MarionTheBull/watchmaker
    def _get_system_params(self):
        """
        Handles the setup of the OS workspace and environment.

        This method also creates the appropriate directories necessary for
        installation.
        """
        if 'Linux' in self.system:
            self.system_drive = '/'
            self._linux_paths()
        elif 'Windows' in self.system:
            self.system_drive = os.environ['SYSTEMDRIVE']
            self._windows_paths()
        else:
            self.logger.fatal('System, {0}, is not recognized?'.format(
                self.system))
            exceptionhandler('The scripts do not recognize this system type: '
                             '{0}'.format(self.system))

        # Create watchmaker directories
        try:
            if not os.path.exists(self.system_params['logdir']):
                os.makedirs(self.system_params['logdir'])
            if not os.path.exists(self.system_params['workingdir']):
                os.makedirs(self.system_params['workingdir'])
        except Exception as exc:
            self.logger.fatal('Could not create a directory in {0}.\n'
                              'Exception: {1}'.format(
                                  self.system_params['prepdir'], exc))
            exceptionhandler(exc)
コード例 #3
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def extract_contents(self, filepath, to_directory, create_dir):
        """

        :param filepath:
        :param to_directory:
        :param create_dir:
        :return:
        """
        opener = None
        mode = None

        if filepath.endswith('.zip'):
            logging.debug('File Type: zip')
            opener, mode = zipfile.ZipFile, 'r'
        elif filepath.endswith('.tar.gz') or filepath.endswith('.tgz'):
            logging.debug('File Type: GZip Tar')
            opener, mode = tarfile.open, 'r:gz'
        elif filepath.endswith('.tar.bz2') or filepath.endswith('.tbz'):
            logging.debug('File Type: Bzip Tar')
            opener, mode = tarfile.open, 'r:bz2'
        else:
            exceptionhandler('Could not extract "{0}" as no appropriate '
                             'extractor is found'.format(filepath))

        if create_dir:
            to_directory = os.sep.join((
                to_directory,
                '.'.join(filepath.split(os.sep)[-1].split('.')[:-1])
            ))

        try:
            os.makedirs(to_directory)
        except OSError:
            if not os.path.isdir(to_directory):
                raise

        cwd = os.getcwd()
        os.chdir(to_directory)

        try:
            openfile = opener(filepath, mode)
            try:
                openfile.extractall()
            finally:
                openfile.close()
        finally:
            os.chdir(cwd)

        print('Extracted file -- \n'
              '    source = {0}\n'
              '    dest   = {1}'.format(filepath, to_directory))
コード例 #4
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def _get_s3_file(url, bucket_name, key_name, destination):
        """
        :param url:
        :param bucket_name:
        :param key_name:
        :param destination:
        :return:
        """

        try:
            import boto3
            from botocore.client import ClientError
        except ImportError as exc:
            exceptionhandler(exc)

        try:
            s3 = boto3.resource("s3")
            s3.meta.client.head_bucket(Bucket=bucket_name)
            s3.Object(bucket_name, key_name).download_file(destination)
        except ClientError as exc:
            logging.error('Bucket does not exist.\n'
                          'bucket = {0}\n'
                          'Exception: {1}'
                          .format(bucket_name, exc))
            raise SystemError('Bucket does not exist.\n'
                              'bucket = {0}\n'
                              'Exception: {1}'
                              .format(bucket_name, exc))
        except Exception as exc:
            logging.error('Unable to download file from S3 bucket.\n'
                          'url = {0}\n'
                          'bucket = {1}\n'
                          'key = {2}\n'
                          'file = {3}\n'
                          'Exception: {4}'
                          .format(url, bucket_name, key_name,
                                  destination, exc))
            raise SystemError('Unable to download file from S3 bucket.\n'
                              'url = {0}\n'
                              'bucket = {1}\n'
                              'key = {2}\n'
                              'file = {3}\n'
                              'Exception: {4}'
                              .format(url, bucket_name, key_name,
                                      destination, exc))
コード例 #5
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def _install_from_yum(self, packages):
        """

        :param packages:
        :return:
        """

        yum_cmd = ['sudo', 'yum', '-y', 'install']
        if isinstance(packages, list):
            yum_cmd.extend(packages)
        else:
            yum_cmd.append(packages)
        rsp = subprocess.call(yum_cmd)
        logging.debug(packages)
        logging.debug('Return code of yum install: {0}'.format(rsp))

        if rsp != 0:
            exceptionhandler('Installing Salt from Yum has failed!')
コード例 #6
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def create_working_dir(self, basedir, prefix):
        """

        :param basedir:
        :param prefix:
        :return:
        """
        logging.info('Creating a working directory.')
        workingdir = None
        original_umask = os.umask(0)
        try:
            workingdir = tempfile.mkdtemp(prefix=prefix, dir=basedir)
        except Exception as exc:
            exceptionhandler('Could not create workingdir in {0}.\n'
                             'Exception: {1}'.format(basedir, exc))
        logging.debug('Working directory: {0}'.format(workingdir))
        self.workingdir = workingdir
        os.umask(original_umask)
コード例 #7
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def cleanup(self):
        """

        :return:
        """
        logging.info('+-' * 40)
        logging.info('Cleanup Time...')
        try:
            logging.debug('{0} being cleaned up.'.format(self.workingdir))
            shutil.rmtree(self.workingdir)
        except Exception as exc:
            # TODO: Update `except` logic
            logging.fatal('Cleanup Failed!\nException: {0}'.format(exc))
            exceptionhandler('Cleanup Failed.\nAborting.')

        logging.info('Removed temporary data in working directory -- {0}'
                     .format(self.workingdir))
        logging.info('Exiting cleanup routine...')
        logging.info('-+' * 40)
コード例 #8
0
ファイル: __init__.py プロジェクト: MarionTheBull/watchmaker
    def install_system(self):
        """
        Initiate the installation of the prepared system.

        After execution the system should be properly provisioned.
        """
        self.logger.info('+' * 80)

        self._get_system_params()
        self.logger.info(self.system_params)

        self._get_scripts_to_execute()
        self.logger.info('Got scripts to execute: {0}.'.format(
            self.config[self.system].keys()))

        if 'Linux' in self.system:
            workers_manager = LinuxWorkersManager(self.s3, self.system_params,
                                                  self.execution_scripts,
                                                  self.saltstates)
        elif 'Windows' in self.system:
            workers_manager = WindowsWorkersManager(self.s3,
                                                    self.system_params,
                                                    self.execution_scripts,
                                                    self.saltstates)
        else:
            exceptionhandler('There is no known System!')

        try:
            workers_manager.worker_cadence()
        except Exception as e:
            exceptionhandler(
                'Execution of the workers cadence has failed. {0}'.format(e))

        if self.noreboot:
            self.logger.info('Detected `noreboot` switch. System will not be '
                             'rebooted.')
        else:
            self.logger.info('Reboot scheduled. System will reboot after the '
                             'script exits.')
            subprocess.call(self.system_params['restart'], shell=True)

        self.logger.info('-' * 80)
コード例 #9
0
ファイル: __init__.py プロジェクト: MarionTheBull/watchmaker
    def _get_scripts_to_execute(self):
        """
        Parses and updates configuration data.

        Returns:
            list: Attribute with configuration data for the target system.
        """
        self._get_config_data()

        scriptstoexecute = self.config[self.system]
        for item in self.config[self.system]:
            try:
                self.config[self.system][item]['Parameters'].update(
                    self.kwargs)
            except Exception as exc:
                self.logger.fatal(
                    'For {0} in {1} the parameters could not be merged'.format(
                        item, self.config_path))
                exceptionhandler(exc)

        self.execution_scripts = scriptstoexecute
コード例 #10
0
ファイル: base.py プロジェクト: MarionTheBull/watchmaker
    def download_file(self, url, filename, sourceiss3bucket):
        """
        :param url:
        :param filename:
        :param sourceiss3bucket:
        :return:
        """
        logging.debug('Downloading: {0}'.format(url))
        logging.debug('Destination: {0}'.format(filename))
        logging.debug('S3: {0}'.format(sourceiss3bucket))

        # TODO Rework this to properly reflect logic flow cleanly.
        if sourceiss3bucket:
            try:
                import boto3
                from botocore.client import ClientError
            except ImportError as exc:
                exceptionhandler(exc)


            bucket_name = url.split('/')[3]
            key_name = '/'.join(url.split('/')[4:])

            logging.debug('Bucket Name: {0}'.format(bucket_name))
            logging.debug('key_name: {0}'.format(key_name))

            try:
                s3 = boto3.resource("s3")
                s3.meta.client.head_bucket(Bucket=bucket_name)
                s3.Object(bucket_name, key_name).download_file(filename)
            except (NameError, ClientError):
                logging.error('NameError: {0}'.format(ClientError))
                try:
                    bucket_name = url.split('/')[2].split('.')[0]
                    key_name = '/'.join(url.split('/')[3:])
                    s3 = boto3.resource("s3")
                    s3.meta.client.head_bucket(Bucket=bucket_name)
                    s3.Object(bucket_name, key_name).download_file(filename)
                except Exception as exc:
                    logging.error(
                        'Unable to download file from S3 bucket.\n'
                        'url = {0}\n'
                        'bucket = {1}\n'
                        'key = {2}\n'
                        'file = {3}\n'
                        'Exception: {4}'
                        .format(url, bucket_name, key_name, filename, exc)
                    )
                    raise SystemError(
                        'Unable to download file from S3 bucket.\n'
                        'url = {0}\n'
                        'bucket = {1}\n'
                        'key = {2}\n'
                        'file = {3}\n'
                        'Exception: {4}'
                        .format(url, bucket_name, key_name, filename, exc)
                    )
            except Exception as exc:
                logging.error(
                    'Unable to download file from S3 bucket.\n'
                    'url = {0}\n'
                    'bucket = {1}\n'
                    'key = {2}\n'
                    'file = {3}\n'
                    'Exception: {4}'
                    .format(url, bucket_name, key_name, filename, exc)
                )
                raise SystemError(
                    'Unable to download file from S3 bucket.\n'
                    'url = {0}\n'
                    'bucket = {1}\n'
                    'key = {2}\n'
                    'file = {3}\n'
                    'Exception: {4}'
                    .format(url, bucket_name, key_name, filename, exc))
            logging.debug('Downloaded file from S3 bucket -- \n'
                          '    url      = {0}\n'
                          '    filename = {1}'.format(url, filename))
        else:
            try:
                response = urllib.request.urlopen(url)
                with open(filename, 'wb') as outfile:
                    shutil.copyfileobj(response, outfile)
            except Exception as exc:
                # TODO: Update `except` logic
                logging.error('Unable to download file from web server.\n'
                              'url = {0}\n'
                              'filename = {1}\n'
                              'Exception: {2}'
                              .format(url, filename, exc))
                raise SystemError('Unable to download file from web server.\n'
                                  'url = {0}\n'
                                  'filename = {1}\n'
                                  'Exception: {2}'
                                  .format(url, filename, exc))
            logging.debug('Downloaded file from web server -- \n'
                          '    url      = {0}\n'
                          '    filename = {1}'.format(url, filename))
コード例 #11
0
ファイル: salt.py プロジェクト: MarionTheBull/watchmaker
    def install(self, configuration, saltstates):
        """
        :param configuration:
        :param saltstates:
        :return:
        """
        try:
            self.config = json.loads(configuration)
        except ValueError:
            exceptionhandler(
                'The configuration passed was not properly formed JSON. '
                'Execution halted.')

        self._prepare_for_install()
        self._install_package()
        self._build_salt_formula()

        logging.info('Setting grain `systemprep`...')
        ent_env = {'enterprise_environment': str(self.entenv)}
        cmd = [
            self.saltcall, '--local', '--retcode-passthrough', 'grains.setval',
            'systemprep',
            str(json.dumps(ent_env))
        ]
        self.call_process(cmd)

        if self.config['oupath']:
            print('Setting grain `join-domain`...')
            oupath = {'oupath': self.config['oupath']}
            cmd = [
                self.saltcall, '--local', '--retcode-passthrough',
                'grains.setval', '"join-domain"',
                json.dumps(oupath)
            ]
            self.call_process(cmd)

        print('Syncing custom salt modules...')
        cmd = [
            self.saltcall, '--local', '--retcode-passthrough',
            'saltutil.sync_all'
        ]
        self.call_process(cmd)

        print('Generating winrepo cache file...')
        cmd = [
            self.saltcall, '--local', '--retcode-passthrough',
            'winrepo.genrepo'
        ]
        self.call_process(cmd)

        print('Refreshing package databse...')
        cmd = [
            self.saltcall, '--local', '--retcode-passthrough', 'pkg.refresh_db'
        ]
        self.call_process(cmd)

        if saltstates:
            self.config['saltstates'] = saltstates
        else:
            logging.info(
                'No command line argument to override configuration file.')

        if 'none' == self.config['saltstates'].lower():
            print('No States were specified. Will not apply any salt states.')
        else:
            if 'highstate' == self.config['saltstates'].lower():
                logging.info(
                    'Detected the States parameter is set to `highstate`. '
                    'Applying the salt `"highstate`" to the system.')
                cmd = [
                    self.saltcall, '--local', '--retcode-passthrough',
                    'state.highstate'
                ]
                cmd.extend(self.saltcall_arguments)
                self.call_process(cmd)

            else:
                logging.info(
                    'Detected the States parameter is set to: {0}. Applying '
                    'the user-defined list of states to the system.'.format(
                        self.config['saltstates']))
                cmd = [
                    self.saltcall, '--local', '--retcode-passthrough',
                    'state.sls', self.config['saltstates']
                ]
                cmd.extend(self.saltcall_arguments)
                self.call_process(cmd)

        logging.info('Salt states all applied successfully! '
                     'Details are in the log {0}'.format(
                         self.salt_results_logfile))

        if self.workingdir:
            self.cleanup()