diff --git a/REFERENCE.md b/REFERENCE.md
index d690f047..4352dd43 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -67,6 +67,7 @@ class { 'python' :
The following parameters are available in the `python` class:
+* [`default_system_version`](#-python--default_system_version)
* [`ensure`](#-python--ensure)
* [`version`](#-python--version)
* [`pip`](#-python--pip)
@@ -92,6 +93,12 @@ The following parameters are available in the `python` class:
* [`anaconda_installer_url`](#-python--anaconda_installer_url)
* [`anaconda_install_path`](#-python--anaconda_install_path)
+##### `default_system_version`
+
+Data type: `Python::Version`
+
+The default version of Python provided by the operating system. Only used as a fallback if Python is not installed yet to determine how to handle some actions that vary depending on the Python version used.
+
##### `ensure`
Data type: `Python::Package::Ensure`
diff --git a/data/common.yaml b/data/common.yaml
new file mode 100644
index 00000000..8d945465
--- /dev/null
+++ b/data/common.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.11"
diff --git a/data/os/Archlinux.yaml b/data/os/Archlinux.yaml
new file mode 100644
index 00000000..3bd58ed5
--- /dev/null
+++ b/data/os/Archlinux.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.13"
diff --git a/data/os/Debian/11.yaml b/data/os/Debian/11.yaml
new file mode 100644
index 00000000..c3b18ece
--- /dev/null
+++ b/data/os/Debian/11.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.9"
diff --git a/data/os/Debian/12.yaml b/data/os/Debian/12.yaml
new file mode 100644
index 00000000..8d945465
--- /dev/null
+++ b/data/os/Debian/12.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.11"
diff --git a/data/os/FreeBSD.yaml b/data/os/FreeBSD.yaml
new file mode 100644
index 00000000..8d945465
--- /dev/null
+++ b/data/os/FreeBSD.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.11"
diff --git a/data/os/Gentoo.yaml b/data/os/Gentoo.yaml
new file mode 100644
index 00000000..68b52939
--- /dev/null
+++ b/data/os/Gentoo.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.12"
diff --git a/data/os/RedHat/8.yaml b/data/os/RedHat/8.yaml
new file mode 100644
index 00000000..5de86ac2
--- /dev/null
+++ b/data/os/RedHat/8.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.6"
diff --git a/data/os/RedHat/9.yaml b/data/os/RedHat/9.yaml
new file mode 100644
index 00000000..c3b18ece
--- /dev/null
+++ b/data/os/RedHat/9.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.9"
diff --git a/data/os/Ubuntu/20.04.yaml b/data/os/Ubuntu/20.04.yaml
new file mode 100644
index 00000000..20aa9c3e
--- /dev/null
+++ b/data/os/Ubuntu/20.04.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.8"
diff --git a/data/os/Ubuntu/22.04.yaml b/data/os/Ubuntu/22.04.yaml
new file mode 100644
index 00000000..383744c0
--- /dev/null
+++ b/data/os/Ubuntu/22.04.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.10"
diff --git a/data/os/Ubuntu/24.04.yaml b/data/os/Ubuntu/24.04.yaml
new file mode 100644
index 00000000..68b52939
--- /dev/null
+++ b/data/os/Ubuntu/24.04.yaml
@@ -0,0 +1 @@
+python::default_system_version: "3.12"
diff --git a/hiera.yaml b/hiera.yaml
new file mode 100644
index 00000000..9cea3e4d
--- /dev/null
+++ b/hiera.yaml
@@ -0,0 +1,23 @@
+---
+version: 5
+
+defaults: # Used for any hierarchy level that omits these keys.
+ datadir: data # This path is relative to hiera.yaml's directory.
+ data_hash: yaml_data # Use the built-in YAML backend.
+
+hierarchy:
+ - name: "archicture"
+ paths:
+ - "architecture/%{facts.os.architecture}.yaml"
+ - "architecture/common.yaml"
+ - name: "osfamily/major release"
+ paths:
+ - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" # Used to distinguish between Debian and Ubuntu
+ - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" #
+ - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" # Used for Solaris
+ - name: "osfamily"
+ paths:
+ - "os/%{facts.os.name}.yaml"
+ - "os/%{facts.os.family}.yaml"
+ - name: 'common'
+ path: 'common.yaml'
diff --git a/manifests/init.pp b/manifests/init.pp
index b457edbd..3f5ac23f 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,5 +1,6 @@
# @summary Installs and manages python, python-dev and gunicorn.
#
+# @param default_system_version The default version of Python provided by the operating system. Only used as a fallback if Python is not installed yet to determine how to handle some actions that vary depending on the Python version used.
# @param ensure Desired installation state for the Python package.
# @param version Python version to install. Beware that valid values for this differ a) by the provider you choose and b) by the osfamily/operatingsystem you are using.
# Allowed values:
@@ -38,6 +39,7 @@
# }
#
class python (
+ Python::Version $default_system_version,
Python::Package::Ensure $ensure = 'present',
Python::Version $version = $facts['os']['family'] ? { 'Archlinux' => 'system', default => '3' },
Python::Package::Ensure $pip = 'present',
diff --git a/manifests/pyvenv.pp b/manifests/pyvenv.pp
index 33b37100..6627a406 100644
--- a/manifests/pyvenv.pp
+++ b/manifests/pyvenv.pp
@@ -41,7 +41,7 @@
if $ensure == 'present' {
$python_version = $version ? {
- 'system' => $facts['python3_version'],
+ 'system' => $facts['python3_version'].lest || { $python::default_system_version },
default => $version,
}
diff --git a/spec/defines/pyvenv_spec.rb b/spec/defines/pyvenv_spec.rb
index ba49fb37..b0578bec 100644
--- a/spec/defines/pyvenv_spec.rb
+++ b/spec/defines/pyvenv_spec.rb
@@ -6,83 +6,94 @@
on_supported_os.each do |os, facts|
next if os == 'gentoo-3-x86_64'
+ let :title do
+ '/opt/env'
+ end
+
context "on #{os}" do
- let :facts do
- # python3 is required to use pyvenv
- facts.merge(
- python3_version: '3.5.1'
- )
- end
- let :title do
- '/opt/env'
+ context 'with default parameters' do
+ let :facts do
+ facts
+ end
+
+ it { is_expected.to compile }
end
- context 'with default parameters' do
- it { is_expected.to contain_file('/opt/env').that_requires('Class[python::install]') }
- it { is_expected.to contain_exec('python_virtualenv_/opt/env').with_command('pyvenv-3.5 --clear /opt/env && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade pip && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade setuptools') }
+ context 'with a specific python3 version' do
+ let :facts do
+ # python3 is required to use pyvenv
+ facts.merge(
+ python3_version: '3.5.1'
+ )
+ end
+
+ context 'with default parameters' do
+ it { is_expected.to contain_file('/opt/env').that_requires('Class[python::install]') }
+ it { is_expected.to contain_exec('python_virtualenv_/opt/env').with_command('pyvenv-3.5 --clear /opt/env && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade pip && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade setuptools') }
+ end
+
+ describe 'when ensure' do
+ context 'is absent' do
+ let :params do
+ {
+ ensure: 'absent'
+ }
+ end
+
+ it {
+ expect(subject).to contain_file('/opt/env').with_ensure('absent').with_purge(true)
+ }
+ end
+ end
end
- describe 'when ensure' do
- context 'is absent' do
+ context "prompt on #{os} with python 3.6" do
+ let :facts do
+ # python 3.6 is required for venv and prompt
+ facts.merge(
+ python3_version: '3.6.1'
+ )
+ end
+ let :title do
+ '/opt/env'
+ end
+
+ context 'with prompt' do
let :params do
{
- ensure: 'absent'
+ prompt: 'custom prompt',
}
end
it {
- expect(subject).to contain_file('/opt/env').with_ensure('absent').with_purge(true)
+ is_expected.to contain_file('/opt/env').that_requires('Class[python::install]')
+ is_expected.to contain_exec('python_virtualenv_/opt/env').with_command('python3.6 -m venv --clear --prompt custom\\ prompt /opt/env && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade pip && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade setuptools')
}
end
end
- end
- context "prompt on #{os} with python 3.6" do
- let :facts do
- # python 3.6 is required for venv and prompt
- facts.merge(
- python3_version: '3.6.1'
- )
- end
- let :title do
- '/opt/env'
- end
-
- context 'with prompt' do
- let :params do
- {
- prompt: 'custom prompt',
- }
+ context "prompt on #{os} with python 3.5" do
+ let :facts do
+ facts.merge(
+ python3_version: '3.5.1'
+ )
+ end
+ let :title do
+ '/opt/env'
end
- it {
- is_expected.to contain_file('/opt/env').that_requires('Class[python::install]')
- is_expected.to contain_exec('python_virtualenv_/opt/env').with_command('python3.6 -m venv --clear --prompt custom\\ prompt /opt/env && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade pip && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade setuptools')
- }
- end
- end
-
- context "prompt on #{os} with python 3.5" do
- let :facts do
- facts.merge(
- python3_version: '3.5.1'
- )
- end
- let :title do
- '/opt/env'
- end
+ context 'with prompt' do
+ let :params do
+ {
+ prompt: 'custom prompt',
+ }
+ end
- context 'with prompt' do
- let :params do
- {
- prompt: 'custom prompt',
+ it {
+ is_expected.to contain_file('/opt/env').that_requires('Class[python::install]')
+ is_expected.to contain_exec('python_virtualenv_/opt/env').with_command('pyvenv-3.5 --clear /opt/env && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade pip && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade setuptools')
}
end
-
- it {
- is_expected.to contain_file('/opt/env').that_requires('Class[python::install]')
- is_expected.to contain_exec('python_virtualenv_/opt/env').with_command('pyvenv-3.5 --clear /opt/env && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade pip && /opt/env/bin/pip --log /opt/env/pip.log install --upgrade setuptools')
- }
end
end
end