Mercurial > repos > other > Puppet
annotate modules/python/manifests/pip.pp @ 482:d83de9b3a62b default tip
Update hiera.yaml within Puppet config
Forgot that we manage it from here. Now has content to match
new packages
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 30 Aug 2024 16:10:36 +0100 |
parents | adf6fe9bbc17 |
children |
rev | line source |
---|---|
272 | 1 # @summary Installs and manages packages from pip. |
2 # | |
3 # @param name must be unique | |
4 # @param pkgname the name of the package. | |
5 # @param ensure Require pip to be available. | |
6 # @param virtualenv virtualenv to run pip in. | |
7 # @param pip_provider version of pip you wish to use. | |
8 # @param url URL to install from. | |
9 # @param owner The owner of the virtualenv being manipulated. | |
10 # @param group The group of the virtualenv being manipulated. | |
11 # @param index Base URL of Python package index. | |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
12 # @param extra_index Base URL of extra Python package index. |
272 | 13 # @param proxy Proxy server to use for outbound connections. |
14 # @param editable If true the package is installed as an editable resource. | |
15 # @param environment Additional environment variables required to install the packages. | |
16 # @param extras Extra features provided by the package which should be installed. | |
17 # @param timeout The maximum time in seconds the "pip install" command should take. | |
18 # @param install_args Any additional installation arguments that will be supplied when running pip install. | |
19 # @param uninstall_args Any additional arguments that will be supplied when running pip uninstall. | |
20 # @param log_dir Log directory | |
21 # @param egg The egg name to use | |
22 # @param umask | |
23 # | |
24 # @example Install Flask to /var/www/project1 using a proxy | |
25 # python::pip { 'flask': | |
26 # virtualenv => '/var/www/project1', | |
27 # proxy => 'http://proxy.domain.com:3128', | |
28 # index => 'http://www.example.com/simple/', | |
29 # } | |
30 # @example Install cx_Oracle with pip | |
31 # python::pip { 'cx_Oracle' : | |
32 # pkgname => 'cx_Oracle', | |
33 # ensure => '5.1.2', | |
34 # virtualenv => '/var/www/project1', | |
35 # owner => 'appuser', | |
36 # proxy => 'http://proxy.domain.com:3128', | |
387 | 37 # environment => ['ORACLE_HOME=/usr/lib/oracle/11.2/client64'], |
272 | 38 # install_args => '-e', |
39 # timeout => 1800, | |
40 # } | |
41 # @example Install Requests with pip3 | |
42 # python::pip { 'requests' : | |
43 # ensure => 'present', | |
44 # pkgname => 'requests', | |
45 # pip_provider => 'pip3', | |
46 # virtualenv => '/var/www/project1', | |
47 # owner => 'root', | |
48 # timeout => 1800 | |
49 # } | |
50 # | |
51 define python::pip ( | |
387 | 52 String[1] $pkgname = $name, |
53 Variant[Enum[present, absent, latest], String[1]] $ensure = present, | |
54 Variant[Enum['system'], Stdlib::Absolutepath] $virtualenv = 'system', | |
55 String[1] $pip_provider = 'pip', | |
56 Variant[Boolean, String] $url = false, | |
57 String[1] $owner = 'root', | |
58 Optional[String[1]] $group = getvar('python::params::group'), | |
59 Optional[Python::Umask] $umask = undef, | |
60 Variant[Boolean,String[1]] $index = false, | |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
61 Variant[Boolean,String[1]] $extra_index = false, |
387 | 62 Optional[Stdlib::HTTPUrl] $proxy = undef, |
63 Any $egg = false, | |
64 Boolean $editable = false, | |
65 Array $environment = [], | |
66 Array $extras = [], | |
67 Optional[String[1]] $install_args = undef, | |
68 Optional[String[1]] $uninstall_args = undef, | |
69 Numeric $timeout = 1800, | |
70 String[1] $log_dir = '/tmp', | |
71 Array[String] $path = ['/usr/local/bin','/usr/bin','/bin', '/usr/sbin'], | |
72 String[1] $exec_provider = 'shell', | |
73 ) { | |
272 | 74 $python_provider = getparam(Class['python'], 'provider') |
75 $python_version = getparam(Class['python'], 'version') | |
76 | |
77 if $virtualenv != 'system' { | |
78 Python::Pyvenv <| |> -> Python::Pip[$name] | |
79 } | |
80 | |
81 # Get SCL exec prefix | |
82 # NB: this will not work if you are running puppet from scl enabled shell | |
83 $exec_prefix = $python_provider ? { | |
84 'scl' => "scl enable ${python_version} -- ", | |
85 'rhscl' => "scl enable ${python_version} -- ", | |
86 default => '', | |
87 } | |
88 | |
89 $_path = $python_provider ? { | |
90 'anaconda' => concat(["${python::anaconda_install_path}/bin"], $path), | |
91 default => $path, | |
92 } | |
93 | |
94 # Parameter validation | |
95 if $virtualenv == 'system' and $owner != 'root' { | |
96 fail('python::pip: root user must be used when virtualenv is system') | |
97 } | |
98 | |
99 $cwd = $virtualenv ? { | |
100 'system' => '/', | |
101 default => $virtualenv, | |
102 } | |
103 | |
104 $log = $virtualenv ? { | |
105 'system' => $log_dir, | |
106 default => $virtualenv, | |
107 } | |
108 | |
109 $pip_env = $virtualenv ? { | |
110 'system' => "${exec_prefix}${pip_provider}", | |
111 default => "${exec_prefix}${virtualenv}/bin/${pip_provider}", | |
112 } | |
113 | |
114 $pypi_index = $index ? { | |
387 | 115 false => '', |
116 default => "--index-url=${index}", | |
117 } | |
272 | 118 |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
119 $pypi_extra_index = $extra_index ? { |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
120 false => '', |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
121 default => "--extra-index-url=${extra_index}", |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
122 } |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
123 |
272 | 124 $proxy_flag = $proxy ? { |
125 undef => '', | |
126 default => "--proxy=${proxy}", | |
127 } | |
128 | |
129 if $editable == true { | |
130 $install_editable = ' -e ' | |
131 } | |
132 else { | |
133 $install_editable = '' | |
134 } | |
135 | |
387 | 136 # TODO: Do more robust argument checking, but below is a start |
137 if ($ensure == absent) and $install_args { | |
272 | 138 fail('python::pip cannot provide install_args with ensure => absent') |
139 } | |
140 | |
387 | 141 if ($ensure == present) and $uninstall_args { |
272 | 142 fail('python::pip cannot provide uninstall_args with ensure => present') |
143 } | |
144 | |
145 if $pkgname =~ /==/ { | |
387 | 146 $parts = split($pkgname, '==') |
272 | 147 $real_pkgname = $parts[0] |
387 | 148 |
272 | 149 $_ensure = $ensure ? { |
150 'absent' => 'absent', | |
151 default => $parts[1], | |
152 } | |
153 } else { | |
154 $real_pkgname = $pkgname | |
387 | 155 $_ensure = $ensure |
272 | 156 } |
157 | |
158 # Check if searching by explicit version. | |
159 if $_ensure =~ /^((19|20)[0-9][0-9]-(0[1-9]|1[1-2])-([0-2][1-9]|3[0-1])|[0-9]+\.\w+\+?\w*(\.\w+)*)$/ { | |
160 $grep_regex = "^${real_pkgname}[[:space:]]\\+(\\?${_ensure}\\()$\\|$\\|, \\|[[:space:]]\\)" | |
161 } else { | |
162 $grep_regex = "^${real_pkgname}[[:space:]].*$" | |
163 } | |
164 | |
165 $extras_string = empty($extras) ? { | |
166 true => '', | |
167 default => sprintf('[%s]',join($extras,',')), | |
168 } | |
169 | |
170 $egg_name = $egg ? { | |
171 false => "${real_pkgname}${extras_string}", | |
172 default => $egg | |
173 } | |
174 | |
175 $source = $url ? { | |
387 | 176 false => "${real_pkgname}${extras_string}", |
177 /^(\/|[a-zA-Z]\:)/ => "'${url}'", | |
272 | 178 /^(git\+|hg\+|bzr\+|svn\+)(http|https|ssh|svn|sftp|ftp|lp|git)(:\/\/).+$/ => "'${url}'", |
387 | 179 default => "'${url}#egg=${egg_name}'", |
272 | 180 } |
181 | |
387 | 182 $pip_install = "${pip_env} --log ${log}/pip.log install" |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
183 $pip_common_args = "${pypi_index} ${pypi_extra_index} ${proxy_flag} ${install_editable} ${source}" |
272 | 184 |
185 # Explicit version out of VCS when PIP supported URL is provided | |
186 if $source =~ /^'(git\+|hg\+|bzr\+|svn\+)(http|https|ssh|svn|sftp|ftp|lp|git)(:\/\/).+'$/ { | |
187 if $_ensure != present and $_ensure != latest { | |
387 | 188 $command = "${pip_install} ${install_args} ${pip_common_args}@${_ensure}#egg=${egg_name}" |
272 | 189 $unless_command = "${pip_env} list | grep -i -e '${grep_regex}'" |
190 } else { | |
387 | 191 $command = "${pip_install} ${install_args} ${pip_common_args}" |
272 | 192 $unless_command = "${pip_env} list | grep -i -e '${grep_regex}'" |
193 } | |
194 } else { | |
195 case $_ensure { | |
196 /^((19|20)[0-9][0-9]-(0[1-9]|1[1-2])-([0-2][1-9]|3[0-1])|[0-9]+\.\w+\+?\w*(\.\w+)*)$/: { | |
197 # Version formats as per http://guide.python-distribute.org/specification.html#standard-versioning-schemes | |
198 # Explicit version. | |
387 | 199 $command = "${pip_install} ${install_args} ${pip_common_args}==${_ensure}" |
272 | 200 $unless_command = "${pip_env} list | grep -i -e '${grep_regex}'" |
201 } | |
202 | |
203 'present': { | |
204 # Whatever version is available. | |
387 | 205 $command = "${pip_install} ${install_args} ${pip_common_args}" |
272 | 206 $unless_command = "${pip_env} list | grep -i -e '${grep_regex}'" |
207 } | |
208 | |
209 'latest': { | |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
210 $pip_version = $facts['pip_version'] |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
211 if $pip_version and versioncmp($pip_version, '21.1') == -1 and versioncmp($pip_version, '20.2.4') == 1 { |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
212 $legacy_resolver = '--use-deprecated=legacy-resolver' |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
213 } else { |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
214 $legacy_resolver = '' |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
215 } |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
216 |
272 | 217 # Unfortunately this is the smartest way of getting the latest available package version with pip as of now |
218 # Note: we DO need to repeat ourselves with "from version" in both grep and sed as on some systems pip returns | |
219 # more than one line with paretheses. | |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
220 $latest_version = join([ |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
221 "${pip_install} ${legacy_resolver} ${pypi_index} ${pypi_extra_index} ${proxy_flag}", |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
222 " ${install_args} ${install_editable} ${real_pkgname}==notreallyaversion 2>&1", |
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
223 " | sed -nE 's/.*\\(from versions: (.*, )*(.*)\\)/\\2/p'", |
387 | 224 ' | tr -d "[:space:]"', |
225 ]) | |
272 | 226 |
227 # Packages with underscores in their names are listed with dashes in their place in `pip freeze` output | |
387 | 228 $pkgname_with_dashes = regsubst($real_pkgname, '_', '-', 'G') |
272 | 229 $grep_regex_pkgname_with_dashes = "^${pkgname_with_dashes}==" |
478
adf6fe9bbc17
Update Puppet modules to latest versions
IBBoard <dev@ibboard.co.uk>
parents:
387
diff
changeset
|
230 $installed_version = join(["${pip_env} freeze --all", " | grep -i -e ${grep_regex_pkgname_with_dashes} | cut -d= -f3", " | tr -d '[:space:]'",]) |
272 | 231 |
387 | 232 $command = "${pip_install} --upgrade ${install_args} ${pip_common_args}" |
272 | 233 $unless_command = "[ \$(${latest_version}) = \$(${installed_version}) ]" |
234 } | |
235 | |
236 default: { | |
237 # Anti-action, uninstall. | |
387 | 238 $command = "echo y | ${pip_env} uninstall ${uninstall_args} ${proxy_flag} ${real_pkgname}" |
272 | 239 $unless_command = "! ${pip_env} list | grep -i -e '${grep_regex}'" |
240 } | |
241 } | |
242 } | |
243 | |
244 $pip_installer = ($ensure == 'absent') ? { | |
245 true => "pip_uninstall_${name}", | |
246 false => "pip_install_${name}", | |
247 } | |
248 | |
249 exec { $pip_installer: | |
250 command => $command, | |
251 unless => $unless_command, | |
252 user => $owner, | |
253 group => $group, | |
254 umask => $umask, | |
255 cwd => $cwd, | |
256 environment => $environment, | |
257 timeout => $timeout, | |
258 path => $_path, | |
259 provider => $exec_provider, | |
260 } | |
261 } |