Beispiel #1
0
def prepare_virtualenv(venv_directory: str, python_bin: str,
                       system_site_packages: bool,
                       requirements: List[str]) -> str:
    """
    Creates a virtual environment and installs the additional python packages

    :param venv_directory: The path for directory where the environment will be created
    :type venv_directory: str
    :param python_bin: Path for python binary
    :type python_bin: str
    :param system_site_packages: Whether to include system_site_packages in your virtualenv.
        See virtualenv documentation for more information.
    :type system_site_packages: bool
    :param requirements: List of additional python packages
    :type requirements: List[str]
    :return: Path to a binary file with Python in a virtual environment.
    :rtype: str
    """
    virtualenv_cmd = _generate_virtualenv_cmd(venv_directory, python_bin,
                                              system_site_packages)
    execute_in_subprocess(virtualenv_cmd)
    pip_cmd = _generate_pip_install_cmd(venv_directory, requirements)
    if pip_cmd:
        execute_in_subprocess(pip_cmd)

    return '{}/bin/python'.format(venv_directory)
Beispiel #2
0
    def execute_callable(self):
        with TemporaryDirectory(prefix='venv') as tmp_dir:
            if self.templates_dict:
                self.op_kwargs['templates_dict'] = self.templates_dict

            input_filename = os.path.join(tmp_dir, 'script.in')
            output_filename = os.path.join(tmp_dir, 'script.out')
            string_args_filename = os.path.join(tmp_dir, 'string_args.txt')
            script_filename = os.path.join(tmp_dir, 'script.py')

            prepare_virtualenv(venv_directory=tmp_dir,
                               python_bin=f'python{self.python_version}'
                               if self.python_version else None,
                               system_site_packages=self.system_site_packages,
                               requirements=self.requirements)

            self._write_args(input_filename)
            self._write_string_args(string_args_filename)
            write_python_script(jinja_context=dict(
                op_args=self.op_args,
                op_kwargs=self.op_kwargs,
                pickling_library=self.pickling_library.__name__,
                python_callable=self.python_callable.__name__,
                python_callable_source=dedent(
                    inspect.getsource(self.python_callable))),
                                filename=script_filename)

            execute_in_subprocess(cmd=[
                f'{tmp_dir}/bin/python', script_filename, input_filename,
                output_filename, string_args_filename
            ])

            return self._read_result(output_filename)
Beispiel #3
0
    def test_should_print_all_messages1(self):
        with self.assertLogs(log) as logs:
            execute_in_subprocess(["bash", "-c", "echo CAT; echo KITTY;"])

        msgs = [record.getMessage() for record in logs.records]

        assert ["Executing cmd: bash -c 'echo CAT; echo KITTY;'", 'Output:', 'CAT', 'KITTY'] == msgs
Beispiel #4
0
    def execute_callable(self):
        with TemporaryDirectory(prefix='venv') as tmp_dir:
            if self.templates_dict:
                self.op_kwargs['templates_dict'] = self.templates_dict
            # generate filenames
            input_filename = os.path.join(tmp_dir, 'script.in')
            output_filename = os.path.join(tmp_dir, 'script.out')
            string_args_filename = os.path.join(tmp_dir, 'string_args.txt')
            script_filename = os.path.join(tmp_dir, 'script.py')

            # set up virtualenv
            python_bin = 'python' + str(
                self.python_version) if self.python_version else None
            prepare_virtualenv(
                venv_directory=tmp_dir,
                python_bin=python_bin,
                system_site_packages=self.system_site_packages,
                requirements=self.requirements,
            )

            self._write_args(input_filename)
            self._write_script(script_filename)
            self._write_string_args(string_args_filename)

            # execute command in virtualenv
            execute_in_subprocess(
                self._generate_python_cmd(tmp_dir, script_filename,
                                          input_filename, output_filename,
                                          string_args_filename))
            return self._read_result(output_filename)
    def execute(self, context):
        hook = GoogleBaseHook(gcp_conn_id=self.gcp_conn_id)
        self.project_id = self.project_id or hook.project_id

        if not self.project_id:
            raise AirflowException(
                "The project id must be passed either as "
                "keyword project_id parameter or as project_id extra "
                "in GCP connection definition. Both are not set!")

        # Write config to a temp file and set the environment variable to point to it.
        # This is to avoid race conditions of reading/writing a single file
        with tempfile.NamedTemporaryFile() as conf_file,\
                patch_environ({KUBE_CONFIG_ENV_VAR: conf_file.name}), \
                hook.provide_authorized_gcloud():
            # Attempt to get/update credentials
            # We call gcloud directly instead of using google-cloud-python api
            # because there is no way to write kubernetes config to a file, which is
            # required by KubernetesPodOperator.
            # The gcloud command looks at the env variable `KUBECONFIG` for where to save
            # the kubernetes config file.
            cmd = [
                "gcloud", "container", "clusters", "get-credentials",
                self.cluster_name, "--zone", self.location, "--project",
                self.project_id
            ]
            if self.use_internal_ip:
                cmd.append('--internal-ip')
            execute_in_subprocess(cmd)

            # Tell `KubernetesPodOperator` where the config file is located
            self.config_file = os.environ[KUBE_CONFIG_ENV_VAR]
            return super().execute(context)
Beispiel #6
0
def install_dependencies(go_module_path: str) -> None:
    """Install dependencies for a Go module.

    :param go_module_path: The path to the directory containing the Go module.
    :return:
    """
    go_mod_tidy = ["go", "mod", "tidy"]
    execute_in_subprocess(go_mod_tidy, cwd=go_module_path)
Beispiel #7
0
    def execute_callable(self):
        with TemporaryDirectory(prefix='venv') as tmp_dir:
            requirements_file_name = f'{tmp_dir}/requirements.txt'

            if not isinstance(self.requirements, str):
                requirements_file_contents = "\n".join(
                    str(dependency) for dependency in self.requirements)
            else:
                requirements_file_contents = self.requirements

            if not self.system_site_packages and self.use_dill:
                requirements_file_contents += '\ndill'

            with open(requirements_file_name, 'w') as file:
                file.write(requirements_file_contents)

            if self.templates_dict:
                self.op_kwargs['templates_dict'] = self.templates_dict

            input_filename = os.path.join(tmp_dir, 'script.in')
            output_filename = os.path.join(tmp_dir, 'script.out')
            string_args_filename = os.path.join(tmp_dir, 'string_args.txt')
            script_filename = os.path.join(tmp_dir, 'script.py')

            prepare_virtualenv(
                venv_directory=tmp_dir,
                python_bin=f'python{self.python_version}'
                if self.python_version else None,
                system_site_packages=self.system_site_packages,
                requirements_file_path=requirements_file_name,
                pip_install_options=self.pip_install_options,
            )

            self._write_args(input_filename)
            self._write_string_args(string_args_filename)
            write_python_script(
                jinja_context=dict(
                    op_args=self.op_args,
                    op_kwargs=self.op_kwargs,
                    pickling_library=self.pickling_library.__name__,
                    python_callable=self.python_callable.__name__,
                    python_callable_source=self.get_python_source(),
                ),
                filename=script_filename,
                render_template_as_native_obj=self.dag.
                render_template_as_native_obj,
            )

            execute_in_subprocess(cmd=[
                f'{tmp_dir}/bin/python',
                script_filename,
                input_filename,
                output_filename,
                string_args_filename,
            ])

            return self._read_result(output_filename)
    def execute(self, context: 'Context') -> Optional[str]:
        hook = GoogleBaseHook(gcp_conn_id=self.gcp_conn_id)
        self.project_id = self.project_id or hook.project_id

        if not self.project_id:
            raise AirflowException(
                "The project id must be passed either as "
                "keyword project_id parameter or as project_id extra "
                "in Google Cloud connection definition. Both are not set!")

        # Write config to a temp file and set the environment variable to point to it.
        # This is to avoid race conditions of reading/writing a single file
        with tempfile.NamedTemporaryFile() as conf_file, patch_environ(
            {KUBE_CONFIG_ENV_VAR:
             conf_file.name}), hook.provide_authorized_gcloud():
            # Attempt to get/update credentials
            # We call gcloud directly instead of using google-cloud-python api
            # because there is no way to write kubernetes config to a file, which is
            # required by KubernetesPodOperator.
            # The gcloud command looks at the env variable `KUBECONFIG` for where to save
            # the kubernetes config file.
            cmd = [
                "gcloud",
                "container",
                "clusters",
                "get-credentials",
                self.cluster_name,
                "--project",
                self.project_id,
            ]
            if self.impersonation_chain:
                if isinstance(self.impersonation_chain, str):
                    impersonation_account = self.impersonation_chain
                elif len(self.impersonation_chain) == 1:
                    impersonation_account = self.impersonation_chain[0]
                else:
                    raise AirflowException(
                        "Chained list of accounts is not supported, please specify only one service account"
                    )

                cmd.extend([
                    '--impersonate-service-account',
                    impersonation_account,
                ])
            if self.regional:
                cmd.append('--region')
            else:
                cmd.append('--zone')
            cmd.append(self.location)
            if self.use_internal_ip:
                cmd.append('--internal-ip')
            execute_in_subprocess(cmd)

            # Tell `KubernetesPodOperator` where the config file is located
            self.config_file = os.environ[KUBE_CONFIG_ENV_VAR]
            return super().execute(context)
    def test_should_print_all_messages1(self):
        with self.assertLogs(
                "airflow.utils.log.logging_mixin.LoggingMixin") as logs:
            process_utils.execute_in_subprocess(
                ["bash", "-c", "echo CAT; echo KITTY;"])

        msgs = [record.getMessage() for record in logs.records]

        self.assertEqual([
            "Executing cmd: bash -c 'echo CAT; echo KITTY;'", 'Output:', 'CAT',
            'KITTY'
        ], msgs)
Beispiel #10
0
def init_module(go_module_name: str, go_module_path: str) -> None:
    """Initialize a Go module. If a ``go.mod`` file already exists, this function
    will do nothing.

    :param go_module_name: The name of the Go module to initialize.
    :param go_module_path: The path to the directory containing the Go module.
    :return:
    """
    if os.path.isfile(os.path.join(go_module_path, "go.mod")):
        return
    go_mod_init_cmd = ["go", "mod", "init", go_module_name]
    execute_in_subprocess(go_mod_init_cmd, cwd=go_module_path)
Beispiel #11
0
def prepare_virtualenv(
    venv_directory: str,
    python_bin: str,
    system_site_packages: bool,
    requirements: Optional[List[str]] = None,
    requirements_file_path: Optional[str] = None,
) -> str:
    """Creates a virtual environment and installs the additional python packages.

    :param venv_directory: The path for directory where the environment will be created.
    :type venv_directory: str
    :param python_bin: Path to the Python executable.
    :type python_bin: str
    :param system_site_packages: Whether to include system_site_packages in your virtualenv.
        See virtualenv documentation for more information.
    :type system_site_packages: bool
    :param requirements: List of additional python packages.
    :type requirements: List[str]
    :param requirements_file_path: Path to the ``requirements.txt`` file.
    :type requirements_file_path: str
    :return: Path to a binary file with Python in a virtual environment.
    :rtype: str
    """
    virtualenv_cmd = _generate_virtualenv_cmd(venv_directory, python_bin,
                                              system_site_packages)
    execute_in_subprocess(virtualenv_cmd)

    if requirements is not None and requirements_file_path is not None:
        raise Exception(
            "Either requirements OR requirements_file_path has to be passed, but not both"
        )

    pip_cmd = None
    if requirements is not None and len(requirements) != 0:
        pip_cmd = _generate_pip_install_cmd_from_list(venv_directory,
                                                      requirements)
    if requirements_file_path is not None and requirements_file_path:
        pip_cmd = _generate_pip_install_cmd_from_file(venv_directory,
                                                      requirements_file_path)

    if pip_cmd:
        execute_in_subprocess(pip_cmd)

    return f'{venv_directory}/bin/python'
Beispiel #12
0
 def test_should_raise_exception(self):
     with self.assertRaises(CalledProcessError):
         process_utils.execute_in_subprocess(["bash", "-c", "exit 1"])