From a96f0386e94b8dae53dd1c3c29f22ba9fee38631 Mon Sep 17 00:00:00 2001 From: Sascha Doering Date: Mon, 8 Feb 2021 16:10:17 +0000 Subject: [PATCH] Add the possibility to specify the pip version in virtual envs --- manifests/pyvenv.pp | 8 ++- spec/acceptance/pyvenv_spec.rb | 55 +++++++++++--------- spec/classes/python_spec.rb | 62 +++++++++++++++++++++++ spec/type_aliases/venv/pipversion_spec.rb | 58 +++++++++++++++++++++ types/venv/pipversion.pp | 6 +++ 5 files changed, 163 insertions(+), 26 deletions(-) create mode 100644 spec/type_aliases/venv/pipversion_spec.rb create mode 100644 types/venv/pipversion.pp diff --git a/manifests/pyvenv.pp b/manifests/pyvenv.pp index 269cf69c..ca710015 100644 --- a/manifests/pyvenv.pp +++ b/manifests/pyvenv.pp @@ -31,6 +31,7 @@ Stdlib::Filemode $mode = '0755', Array[Stdlib::Absolutepath] $path = ['/bin', '/usr/bin', '/usr/sbin', '/usr/local/bin',], Array $environment = [], + Python::Venv::PipVersion $pip_version = 'latest', ) { include python @@ -78,8 +79,13 @@ $pip_cmd = "${python::exec_prefix}${venv_dir}/bin/pip" + $pip_upgrade = ($pip_version != 'latest') ? { + true => "--upgrade 'pip ${pip_version}'", + false => '--upgrade pip', + } + exec { "python_virtualenv_${venv_dir}": - command => "${virtualenv_cmd} --clear ${system_pkgs_flag} ${venv_dir} && ${pip_cmd} --log ${venv_dir}/pip.log install --upgrade pip && ${pip_cmd} --log ${venv_dir}/pip.log install --upgrade setuptools", + command => "${virtualenv_cmd} --clear ${system_pkgs_flag} ${venv_dir} && ${pip_cmd} --log ${venv_dir}/pip.log install ${pip_upgrade} && ${pip_cmd} --log ${venv_dir}/pip.log install --upgrade setuptools", user => $owner, creates => "${venv_dir}/bin/activate", path => $_path, diff --git a/spec/acceptance/pyvenv_spec.rb b/spec/acceptance/pyvenv_spec.rb index c137d0b9..a6234637 100644 --- a/spec/acceptance/pyvenv_spec.rb +++ b/spec/acceptance/pyvenv_spec.rb @@ -19,11 +19,12 @@ class { 'python': system => true, } python::pyvenv { '/opt/agent/venv': - ensure => 'present', - systempkgs => true, - owner => 'agent', - group => 'agent', - mode => '0755', + ensure => 'present', + systempkgs => true, + owner => 'agent', + group => 'agent', + mode => '0755', + pip_version => '<= 20.3.4', } PUPPET @@ -50,11 +51,12 @@ class { 'python': system => true, } python::pyvenv { '/opt/agent/venv': - ensure => 'present', - systempkgs => true, - owner => 'agent', - group => 'agent', - mode => '0755', + ensure => 'present', + systempkgs => true, + owner => 'agent', + group => 'agent', + mode => '0755', + pip_version => '<= 20.3.4', } python::pip { 'agent' : ensure => 'latest', @@ -89,11 +91,12 @@ class { 'python': system => true, } python::pyvenv { '/opt/agent/venv': - ensure => 'present', - systempkgs => true, - owner => 'agent', - group => 'agent', - mode => '0755', + ensure => 'present', + systempkgs => true, + owner => 'agent', + group => 'agent', + mode => '0755', + pip_version => '<= 20.3.4', } python::pip { 'agent' : virtualenv => '/opt/agent/venv', @@ -125,11 +128,12 @@ class { 'python': system => true, } python::pyvenv { '/opt/agent/venv': - ensure => 'present', - systempkgs => false, - owner => 'agent', - group => 'agent', - mode => '0755', + ensure => 'present', + systempkgs => false, + owner => 'agent', + group => 'agent', + mode => '0755', + pip_version => '<= 20.3.4', } python::pip { 'agent' : virtualenv => '/opt/agent/venv', @@ -161,11 +165,12 @@ class { 'python': system => true, } python::pyvenv { '/opt/agent/venv': - ensure => 'present', - systempkgs => false, - owner => 'agent', - group => 'agent', - mode => '0755', + ensure => 'present', + systempkgs => false, + owner => 'agent', + group => 'agent', + mode => '0755', + pip_version => '<= 20.3.4', } python::pip { 'agent' : ensure => '0.1.2', diff --git a/spec/classes/python_spec.rb b/spec/classes/python_spec.rb index f8223d2d..bc5af262 100644 --- a/spec/classes/python_spec.rb +++ b/spec/classes/python_spec.rb @@ -97,6 +97,68 @@ end end + describe 'with python::python_pyvenvs and pip version defined' do + context 'with two pyenvs' do + let(:params) do + { + python_pyvenvs: { + '/opt/env1' => { + version: '3.8', + pip_version: 'latest' + }, + '/opt/env2' => { + version: '3.8', + pip_version: '<= 20.3.4' + } + } + } + end + + it { is_expected.to compile } + + it { is_expected.to contain_python__pyvenv('/opt/env1').with_ensure('present') } + it { is_expected.to contain_python__pyvenv('/opt/env2').with_ensure('present') } + it { is_expected.to contain_exec('python_virtualenv_/opt/env1') + .with( + command: 'python3.8 -m venv --clear /opt/env1 && /opt/env1/bin/pip --log /opt/env1/pip.log install --upgrade pip && /opt/env1/bin/pip --log /opt/env1/pip.log install --upgrade setuptools', + user: 'root', + creates: '/opt/env1/bin/activate', + path: [ + '/bin', + '/usr/bin', + '/usr/sbin', + '/usr/local/bin' + ], + cwd: '/tmp', + environment: [], + timeout: 600, + unless: %r{^grep '\^\[\\t \]\*VIRTUAL_ENV=\[\\\\'\\\"\]\*/opt/env1\[\\\"\\\\'\]\[\\t \]\*\$' /opt/env1/bin/activate$} + ) + .that_requires('File[/opt/env1]') + } + it { is_expected.to contain_exec('python_virtualenv_/opt/env2') + .with( + command: 'python3.8 -m venv --clear /opt/env2 && /opt/env2/bin/pip --log /opt/env2/pip.log install --upgrade \'pip <= 20.3.4\' && /opt/env2/bin/pip --log /opt/env2/pip.log install --upgrade setuptools', + user: 'root', + creates: '/opt/env2/bin/activate', + path: [ + '/bin', + '/usr/bin', + '/usr/sbin', + '/usr/local/bin' + ], + cwd: '/tmp', + environment: [], + timeout: 600, + unless: %r{^grep '\^\[\\t \]\*VIRTUAL_ENV=\[\\\\'\\\"\]\*/opt/env2\[\\\"\\\\'\]\[\\t \]\*\$' /opt/env2/bin/activate$} + ) + .that_requires('File[/opt/env2]') + } + it { is_expected.to contain_file('/opt/env1') } + it { is_expected.to contain_file('/opt/env2') } + end + end + describe 'with manage_gunicorn' do context 'true' do let(:params) { { manage_gunicorn: true } } diff --git a/spec/type_aliases/venv/pipversion_spec.rb b/spec/type_aliases/venv/pipversion_spec.rb new file mode 100644 index 00000000..986eeb1e --- /dev/null +++ b/spec/type_aliases/venv/pipversion_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe 'Python::Venv::PipVersion' do + describe 'valid values' do + [ + '< 1', + '< 0.1', + '< 1.2.3', + '< 1.2.3.40', + '<= 1', + '<= 0.1', + '<= 1.2.3', + '<= 1.2.3.40', + '> 1', + '> 0.1', + '> 1.2.3', + '> 1.2.3.40', + '>= 1', + '>= 0.1', + '>= 1.2.3', + '>= 1.2.3.40', + '== 1', + '== 0.1', + '== 1.2.3', + '== 1.2.3.40', + ].each do |value| + describe value.inspect do + it { + is_expected.to allow_value(value) + } + end + end + end + + describe 'invalid values' do + [ + '+ 1', + '- 0.1', + '< -1', + '< 1.+2.3.40', + '<=', + '<= 0.-1', + '<= 1.f.3', + '1.2.3.0', + 'pip > 1', + 'all', + -1, + 65_536, + :undef, + ].each do |value| + describe value.inspect do + it { + is_expected.not_to allow_value(value) + } + end + end + end +end diff --git a/types/venv/pipversion.pp b/types/venv/pipversion.pp new file mode 100644 index 00000000..37584264 --- /dev/null +++ b/types/venv/pipversion.pp @@ -0,0 +1,6 @@ +# @summary A version type to ensure a specific Pip version in a virtual env. +# +type Python::Venv::PipVersion = Pattern[ + /^(<|>|<=|>=|==) [0-9]*(\.[0-9]+)*$/, + /\Alatest\Z/ +]