diff --git a/.fixtures.yml b/.fixtures.yml
index 160f990..c450cd4 100644
--- a/.fixtures.yml
+++ b/.fixtures.yml
@@ -3,3 +3,6 @@ fixtures:
archive: https://github.com/voxpupuli/puppet-archive.git
stdlib: https://github.com/puppetlabs/puppetlabs-stdlib.git
systemd: https://github.com/voxpupuli/puppet-systemd.git
+ apt: https://github.com/puppetlabs/puppetlabs-apt.git
+ yum: https://github.com/voxpupuli/puppet-yum.git
+ augeas_core: https://github.com/puppetlabs/puppetlabs-augeas_core.git # required by puppet-yum
diff --git a/REFERENCE.md b/REFERENCE.md
index 7119083..94f8c26 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -14,6 +14,9 @@
* `caddy::config`: This class handles the Caddy config.
* `caddy::install`: This class handles the Caddy archive.
+* `caddy::install::github`: This class handles Caddy installation from the github releases
+* `caddy::install::repo`: This class handles Caddy installation from a package repository
+* `caddy::install::site`: This class handles Caddy installation from the github releases
* `caddy::service`: This class handles the Caddy service.
### Defined types
@@ -82,6 +85,10 @@ The following parameters are available in the `caddy` class:
* [`service_name`](#-caddy--service_name)
* [`service_ensure`](#-caddy--service_ensure)
* [`service_enable`](#-caddy--service_enable)
+* [`manage_repo`](#-caddy--manage_repo)
+* [`distribution_channel`](#-caddy--distribution_channel)
+* [`package_name`](#-caddy--package_name)
+* [`package_ensure`](#-caddy--package_ensure)
##### `version`
@@ -93,9 +100,12 @@ Default value: `'2.0.0'`
##### `install_method`
-Data type: `Optional[Enum['github']]`
+Data type: `Optional[Enum['github','repo']]`
-Which source is used.
+Which source to use for the Caddy installation. See https://caddyserver.com/docs/install.
+* `undef` (default) - download from the official Caddy site
+* `github` - download from Github releases
+* `repo` - install from an OS repository
Default value: `undef`
@@ -103,7 +113,7 @@ Default value: `undef`
Data type: `Stdlib::Absolutepath`
-Directory where the Caddy binary is stored.
+Directory where the Caddy binary is stored. Not used when $install_method is 'repo'.
Default value: `'/opt/caddy'`
@@ -279,7 +289,7 @@ Default value: `true`
Data type: `String[1]`
-Customise the name of the system service
+Customise the name of the system service.
Default value: `'caddy'`
@@ -287,7 +297,7 @@ Default value: `'caddy'`
Data type: `Stdlib::Ensure::Service`
-Whether the service should be running or stopped
+Whether the service should be running or stopped.
Default value: `'running'`
@@ -295,10 +305,42 @@ Default value: `'running'`
Data type: `Boolean`
-Whether the service should be enabled or disabled
+Whether the service should be enabled or disabled.
Default value: `true`
+##### `manage_repo`
+
+Data type: `Boolean`
+
+Whether the APT/YUM(COPR) repository should be installed. Only relevant when $install_method is 'repo'.
+
+Default value: `true`
+
+##### `distribution_channel`
+
+Data type: `Enum['stable','testing']`
+
+Whether to use stable or testing distribution channel. Only relevant on Debian family and only when $install_method is 'repo'.
+
+Default value: `'stable'`
+
+##### `package_name`
+
+Data type: `String[1]`
+
+Name of the caddy package to use. Only relevant when $install_method is 'repo'.
+
+Default value: `'caddy'`
+
+##### `package_ensure`
+
+Data type: `String[1]`
+
+Whether to install or remove the caddy package. Only relevant when $install_method is 'repo'.
+
+Default value: `$version`
+
## Defined types
### `caddy::vhost`
diff --git a/manifests/init.pp b/manifests/init.pp
index a91c55f..446e237 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -19,10 +19,13 @@
# Which version is used.
#
# @param install_method
-# Which source is used.
+# Which source to use for the Caddy installation. See https://caddyserver.com/docs/install.
+# * `undef` (default) - download from the official Caddy site
+# * `github` - download from Github releases
+# * `repo` - install from an OS repository
#
# @param install_path
-# Directory where the Caddy binary is stored.
+# Directory where the Caddy binary is stored. Not used when $install_method is 'repo'.
#
# @param manage_user
# Whether or not the module should create the user.
@@ -88,17 +91,29 @@
# Whether or not the module should manage the service.
#
# @param service_name
-# Customise the name of the system service
+# Customise the name of the system service.
#
# @param service_ensure
-# Whether the service should be running or stopped
+# Whether the service should be running or stopped.
#
# @param service_enable
-# Whether the service should be enabled or disabled
+# Whether the service should be enabled or disabled.
+#
+# @param manage_repo
+# Whether the APT/YUM(COPR) repository should be installed. Only relevant when $install_method is 'repo'.
+#
+# @param distribution_channel
+# Whether to use stable or testing distribution channel. Only relevant on Debian family and only when $install_method is 'repo'.
+#
+# @param package_name
+# Name of the caddy package to use. Only relevant when $install_method is 'repo'.
+#
+# @param package_ensure
+# Whether to install or remove the caddy package. Only relevant when $install_method is 'repo'.
#
class caddy (
String[1] $version = '2.0.0',
- Optional[Enum['github']] $install_method = undef,
+ Optional[Enum['github','repo']] $install_method = undef,
Stdlib::Absolutepath $install_path = '/opt/caddy',
Boolean $manage_user = true,
String[1] $caddy_user = 'caddy',
@@ -124,10 +139,15 @@
String[1] $service_name = 'caddy',
Stdlib::Ensure::Service $service_ensure = 'running',
Boolean $service_enable = true,
+ Boolean $manage_repo = true,
+ Enum['stable','testing'] $distribution_channel = 'stable',
+ String[1] $package_name = 'caddy',
+ String[1] $package_ensure = $version,
) {
case $caddy_architecture {
'x86_64', 'amd64': { $arch = 'amd64' }
'x86' : { $arch = '386' }
+ 'aarch64' : { $arch = 'arm64' }
default: {
$arch = $caddy_architecture
warning("arch ${arch} may not be supported.")
diff --git a/manifests/install.pp b/manifests/install.pp
index 61bc2c3..6bb8e7b 100644
--- a/manifests/install.pp
+++ b/manifests/install.pp
@@ -9,6 +9,7 @@
$bin_file = "${caddy::install_path}/caddy"
case $caddy::install_method {
+ 'repo': { contain caddy::install::repo }
'github': {
$caddy_url = 'https://github.com/caddyserver/caddy/releases/download'
$caddy_dl_url = "${caddy_url}/v${caddy::version}/caddy_${caddy::version}_linux_${caddy::arch}.tar.gz"
@@ -37,6 +38,21 @@
}
$caddy_source = "/var/cache/caddy-${caddy::version}/caddy"
+
+ file { $caddy::install_path:
+ ensure => directory,
+ owner => $caddy::caddy_user,
+ group => $caddy::caddy_group,
+ mode => '0755',
+ }
+
+ file { $bin_file:
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ source => $caddy_source,
+ }
}
default: {
$caddy_url = 'https://caddyserver.com/api/download'
@@ -60,21 +76,21 @@
source => $caddy_dl_url,
replace => false, # Don't download the file on every run
}
- }
- }
- file { $caddy::install_path:
- ensure => directory,
- owner => $caddy::caddy_user,
- group => $caddy::caddy_group,
- mode => '0755',
- }
+ file { $caddy::install_path:
+ ensure => directory,
+ owner => $caddy::caddy_user,
+ group => $caddy::caddy_group,
+ mode => '0755',
+ }
- file { $bin_file:
- ensure => file,
- owner => 'root',
- group => 'root',
- mode => '0755',
- source => $caddy_source,
+ file { $bin_file:
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ source => $caddy_source,
+ }
+ }
}
}
diff --git a/manifests/install/repo.pp b/manifests/install/repo.pp
new file mode 100644
index 0000000..a14a115
--- /dev/null
+++ b/manifests/install/repo.pp
@@ -0,0 +1,44 @@
+# @summary
+# This class handles Caddy installation from a package repository
+#
+# @api private
+#
+class caddy::install::repo {
+ assert_private()
+
+ case $facts['os']['family'] {
+ 'Debian': {
+ include apt
+
+ if $caddy::manage_repo {
+ apt::source { 'caddy':
+ location => "https://dl.cloudsmith.io/public/caddy/${caddy::distribution_channel}/deb/debian",
+ release => 'any-version',
+ repos => 'main',
+ key => {
+ name => "caddy-${caddy::distribution_channel}-archive-keyring.asc",
+ source => "https://dl.cloudsmith.io/public/caddy/${caddy::distribution_channel}/gpg.key",
+ },
+ before => Package[$caddy::package_name],
+ }
+ }
+ }
+ 'RedHat': {
+ include yum
+
+ if $caddy::manage_repo {
+ yum::copr { '@caddy/caddy':
+ ensure => 'enabled',
+ before => Package[$caddy::package_name],
+ }
+ }
+ }
+ default: {
+ fail("OS family ${facts['os']['family']} has no support for 'repo' install method")
+ }
+ }
+
+ package { $caddy::package_name:
+ ensure => $caddy::package_ensure.lest || { 'installed' },
+ }
+}
diff --git a/spec/acceptance/init_spec.rb b/spec/acceptance/init_spec.rb
index f69e57a..e7fe952 100644
--- a/spec/acceptance/init_spec.rb
+++ b/spec/acceptance/init_spec.rb
@@ -56,6 +56,35 @@ class { 'caddy':
end
end
+ context 'when installing from repo' do
+ # Debian repo has multiple versions
+ # RedHat repo has just the latest version at the moment
+ let(:use_version) do
+ case shell('/opt/puppetlabs/bin/facter os.family').stdout
+ when 'Debian'
+ '2.8.3'
+ else
+ latest_release[1..]
+ end
+ end
+
+ it_behaves_like 'an idempotent resource' do
+ let(:manifest) do
+ <<~PUPPET
+ class { 'caddy':
+ install_method => 'repo',
+ version => '#{use_version}',
+ }
+ PUPPET
+ end
+ end
+
+ describe command('caddy version') do
+ its(:exit_status) { is_expected.to eq 0 }
+ its(:stdout) { is_expected.to start_with "v#{use_version}" }
+ end
+ end
+
context 'with vhosts' do
it_behaves_like 'an idempotent resource' do
let(:manifest) do
diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb
index 7a57a54..4c022d2 100644
--- a/spec/classes/init_spec.rb
+++ b/spec/classes/init_spec.rb
@@ -11,9 +11,14 @@
case facts[:os]['family']
when 'Debian'
- caddy_shell = '/usr/sbin/nologin'
+ caddy_shell = '/usr/sbin/nologin'
+ has_repo = true
when 'RedHat'
- caddy_shell = '/sbin/nologin'
+ caddy_shell = '/sbin/nologin'
+ has_repo = true
+ else
+ caddy_shell = '/sbin/nologin'
+ has_repo = false
end
context 'with defaults for all parameters' do
@@ -171,6 +176,74 @@
end
end
+ context 'with install_method => repo' do
+ let(:params) { { install_method: 'repo' } }
+
+ case facts[:os]['family']
+ when 'Debian'
+ context 'on Debian family' do
+ it { is_expected.to contain_class('apt') }
+
+ it do
+ is_expected.to contain_apt__source('caddy').
+ with_location(%r{stable}).
+ with_key(
+ 'name' => %r{stable},
+ 'source' => %r{stable}
+ ).that_comes_before('Package[caddy]')
+ end
+
+ it { is_expected.to contain_package('caddy').with_ensure('2.0.0') }
+
+ context 'with manage_repo => false' do
+ let(:params) { super().merge(manage_repo: false) }
+
+ it { is_expected.not_to contain_apt__source('caddy') }
+ end
+
+ context 'with distribution_channel => testing' do
+ let(:params) { super().merge(distribution_channel: 'testing') }
+
+ it do
+ is_expected.to contain_apt__source('caddy').
+ with_location(%r{testing}).
+ with_key(
+ 'name' => %r{testing},
+ 'source' => %r{testing}
+ ).that_comes_before('Package[caddy]')
+ end
+ end
+ end
+ when 'RedHat'
+ context 'on RedHat family' do
+ it { is_expected.to contain_class('yum') }
+ it { is_expected.to contain_package('caddy').with_ensure('2.0.0') }
+
+ context 'with manage_repo => false' do
+ let(:params) { super().merge(manage_repo: false) }
+
+ it { is_expected.not_to contain_yum__copr('@caddy/caddy').with_ensure('enabled').that_comes_before('Package[caddy]') }
+ end
+ end
+ else
+ it { is_expected.to raise_error(%r{has no support for 'repo' install method}) }
+ end
+
+ if has_repo
+ context 'with package_name => test' do
+ let(:params) { super().merge(package_name: 'test') }
+
+ it { is_expected.to contain_package('test').with_ensure('2.0.0') }
+ end
+
+ context 'with package_ensure => 2.3.4' do
+ let(:params) { super().merge(package_ensure: '2.3.4') }
+
+ it { is_expected.to contain_package('caddy').with_ensure('2.3.4') }
+ end
+ end
+ end
+
context 'with caddy_user => test_user' do
let(:params) { { caddy_user: 'test_user' } }
diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb
index 2681792..1804fe8 100644
--- a/spec/spec_helper_acceptance.rb
+++ b/spec/spec_helper_acceptance.rb
@@ -5,6 +5,6 @@
require 'voxpupuli/acceptance/spec_helper_acceptance'
-configure_beaker(modules: :metadata)
+configure_beaker(modules: :fixtures)
Dir['./spec/support/acceptance/**/*.rb'].sort.each { |f| require f }