summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--composer.json40
-rw-r--r--composer.lock1348
-rw-r--r--src/BaseServerSetup.php96
-rw-r--r--src/unattended-upgrades/auto-upgrades.twig25
-rw-r--r--src/unattended-upgrades/unattended-upgrades.php140
-rw-r--r--src/unattended-upgrades/unattended-upgrades.twig117
-rw-r--r--test/Vagrantfile70
-rw-r--r--test/config.php17
9 files changed, 1855 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c58d7a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/vendor/
+/test/.vagrant/
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..b7eadb6
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "dweipert/base-server-setup",
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "require": {
+ "php": "^8.0",
+ "php-iac/role": "*"
+ },
+ "require-dev": {
+ "php-iac/modules": "*",
+ "php-iac/php-iac": "*"
+ },
+ "autoload": {
+ "psr-4": {
+ "Dweipert\\DevOps\\BaseServerSetup\\": "src"
+ }
+ },
+ "repositories": [
+ {
+ "type": "path",
+ "url": "../role"
+ },
+ {
+ "type": "path",
+ "url": "../php-iac-cli"
+ },
+ {
+ "type": "path",
+ "url": "../modules"
+ }
+ ],
+ "minimum-stability": "dev",
+ "scripts": {
+ "test": "phpiac --config=./test/config.php"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..b52935a
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1348 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "31ceed36455e6519a1b2322dace22686",
+ "packages": [
+ {
+ "name": "php-iac/role",
+ "version": "dev-main",
+ "dist": {
+ "type": "path",
+ "url": "../role",
+ "reference": "a8ddac7859f7139ce13d244c7dd39fae6ed07db0"
+ },
+ "require": {
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "php-iac/modules": "*",
+ "php-iac/php-iac": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPIAC\\Role\\": "src"
+ }
+ },
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "transport-options": {
+ "relative": true
+ }
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "paragonie/constant_time_encoding",
+ "version": "v2.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
+ "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6|^7|^8|^9",
+ "vimeo/psalm": "^1|^2|^3|^4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "time": "2020-12-06T15:14:20+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v9.99.100",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">= 7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "time": "2020-10-15T08:29:30+00:00"
+ },
+ {
+ "name": "petrknap/php-singleton",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/petrknap/php-singleton.git",
+ "reference": "dec131d0d6c72dd76b5a5c7940f04f14f5df7a20"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/petrknap/php-singleton/zipball/dec131d0d6c72dd76b5a5c7940f04f14f5df7a20",
+ "reference": "dec131d0d6c72dd76b5a5c7940f04f14f5df7a20",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PetrKnap\\Php\\Singleton\\": "src/Singleton"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Petr Knap",
+ "email": "dev@petrknap.cz",
+ "homepage": "http://petrknap.cz"
+ }
+ ],
+ "description": "Singleton pattern for PHP",
+ "homepage": "https://github.com/petrknap/php-singleton",
+ "support": {
+ "issues": "https://github.com/petrknap/php-singleton/issues",
+ "source": "https://github.com/petrknap/php-singleton/tree/master"
+ },
+ "time": "2016-09-22T07:59:18+00:00"
+ },
+ {
+ "name": "php-iac/modules",
+ "version": "dev-main",
+ "dist": {
+ "type": "path",
+ "url": "../modules",
+ "reference": "d4d5ae3bb6566311b2d42cf888e463b62f6cf0dc"
+ },
+ "require": {
+ "php": "^8.0",
+ "twig/twig": "^3.0"
+ },
+ "require-dev": {
+ "php-iac/php-iac": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPIAC\\Modules\\": "src"
+ }
+ },
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "transport-options": {
+ "relative": true
+ }
+ },
+ {
+ "name": "php-iac/php-iac",
+ "version": "dev-main",
+ "dist": {
+ "type": "path",
+ "url": "../php-iac-cli",
+ "reference": "3983548e7c0f107fa7b7cc3c4c36aa009590b481"
+ },
+ "require": {
+ "petrknap/php-singleton": "^1.0",
+ "php": "^8.0",
+ "php-iac/modules": "*",
+ "php-iac/role": "*",
+ "phpseclib/phpseclib": "^3.0",
+ "symfony/console": "^5.2"
+ },
+ "bin": [
+ "bin/phpiac"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPIAC\\": "src"
+ }
+ },
+ "scripts": {
+ "compile": [
+ "@php -dphar.readonly=0 bin/compile"
+ ]
+ },
+ "license": [
+ "AGPL-3.0-only"
+ ],
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "transport-options": {
+ "relative": true
+ }
+ },
+ {
+ "name": "phpseclib/phpseclib",
+ "version": "3.0.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpseclib/phpseclib.git",
+ "reference": "d9615a6fb970d9933866ca8b4036ec3407b020b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d9615a6fb970d9933866ca8b4036ec3407b020b6",
+ "reference": "d9615a6fb970d9933866ca8b4036ec3407b020b6",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/constant_time_encoding": "^1|^2",
+ "paragonie/random_compat": "^1.4|^2.0|^9.99.99",
+ "php": ">=5.6.1"
+ },
+ "require-dev": {
+ "phing/phing": "~2.7",
+ "phpunit/phpunit": "^5.7|^6.0|^9.4",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "suggest": {
+ "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+ "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+ "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+ "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "phpseclib/bootstrap.php"
+ ],
+ "psr-4": {
+ "phpseclib3\\": "phpseclib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jim Wigginton",
+ "email": "terrafrost@php.net",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Patrick Monnerat",
+ "email": "pm@datasphere.ch",
+ "role": "Developer"
+ },
+ {
+ "name": "Andreas Fischer",
+ "email": "bantu@phpbb.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Hans-Jürgen Petrich",
+ "email": "petrich@tronic-media.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Graham Campbell",
+ "email": "graham@alt-three.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+ "homepage": "http://phpseclib.sourceforge.net",
+ "keywords": [
+ "BigInteger",
+ "aes",
+ "asn.1",
+ "asn1",
+ "blowfish",
+ "crypto",
+ "cryptography",
+ "encryption",
+ "rsa",
+ "security",
+ "sftp",
+ "signature",
+ "signing",
+ "ssh",
+ "twofish",
+ "x.509",
+ "x509"
+ ],
+ "support": {
+ "issues": "https://github.com/phpseclib/phpseclib/issues",
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/terrafrost",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/phpseclib",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-19T03:20:48+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.1.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/1.1.x"
+ },
+ "time": "2021-03-05T17:36:06+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "5.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "1d077bd682f7c0794d5f5b794b16e2b30febec6b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/1d077bd682f7c0794d5f5b794b16e2b30febec6b",
+ "reference": "1d077bd682f7c0794d5f5b794b16e2b30febec6b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php73": "^1.8",
+ "symfony/polyfill-php80": "^1.15",
+ "symfony/service-contracts": "^1.1|^2",
+ "symfony/string": "^5.1"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<4.4",
+ "symfony/dotenv": "<5.1",
+ "symfony/event-dispatcher": "<4.4",
+ "symfony/lock": "<4.4",
+ "symfony/process": "<4.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "^4.4|^5.0",
+ "symfony/dependency-injection": "^4.4|^5.0",
+ "symfony/event-dispatcher": "^4.4|^5.0",
+ "symfony/lock": "^4.4|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "symfony/var-dumper": "^4.4|^5.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "default-branch": true,
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v5.3.0-BETA1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-16T17:36:28+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
+ "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-23T23:28:01+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+ "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "053f7184175d5417c933817341c5cc0053ddacd5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/053f7184175d5417c933817341c5cc0053ddacd5",
+ "reference": "053f7184175d5417c933817341c5cc0053ddacd5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
+ "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "298b87cbbe99cb2c9f88fb1d1de78833b64b483e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/298b87cbbe99cb2c9f88fb1d1de78833b64b483e",
+ "reference": "298b87cbbe99cb2c9f88fb1d1de78833b64b483e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-19T09:32:22+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php73",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php73.git",
+ "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010",
+ "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php73\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
+ "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb",
+ "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "psr/container": "^1.1"
+ },
+ "suggest": {
+ "symfony/service-implementation": ""
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v2.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-01T10:43:52+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "5.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "01454c66c88a6bb4449dcdeb913e463e075f331b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/01454c66c88a6bb4449dcdeb913e463e075f331b",
+ "reference": "01454c66c88a6bb4449dcdeb913e463e075f331b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php80": "~1.15"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^4.4|^5.0",
+ "symfony/http-client": "^4.4|^5.0",
+ "symfony/translation-contracts": "^1.1|^2",
+ "symfony/var-exporter": "^4.4|^5.0"
+ },
+ "default-branch": true,
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "files": [
+ "Resources/functions.php"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v5.3.0-BETA1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-17T17:12:23+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "3.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "32d72de1885889452f3d8aa298a90b04d263651b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/32d72de1885889452f3d8aa298a90b04d263651b",
+ "reference": "32d72de1885889452f3d8aa298a90b04d263651b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/3.x"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-15T10:09:30+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "dev",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "^8.0"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.0.0"
+}
diff --git a/src/BaseServerSetup.php b/src/BaseServerSetup.php
new file mode 100644
index 0000000..7ff1efb
--- /dev/null
+++ b/src/BaseServerSetup.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Dweipert\DevOps\BaseServerSetup;
+
+use PHPIAC\Module\State;
+use PHPIAC\Modules\AptModule;
+use PHPIAC\Modules\CopyModule;
+use PHPIAC\Modules\GitModule;
+use PHPIAC\Modules\TemplateModule;
+use PHPIAC\Modules\UfwModule;
+use PHPIAC\Modules\UserModule;
+use PHPIAC\Role\RoleInterface;
+use PHPIAC\Task;
+
+class BaseServerSetup implements RoleInterface
+{
+ public function __invoke(array $config = []): array
+ {
+ $config = array_replace_recursive(
+ include __DIR__ . '/unattended-upgrades/unattended-upgrades.php',
+ [
+ 'unattended_origins_patterns' => [
+ 'o=${distro_id},a=${distro_codename}',
+ 'o=${distro_id},a=${distro_codename}-security',
+ ],
+ 'unattended_mail' => $config['mail'],
+ 'unattended_automatic_reboot' => true,
+ 'unattended_syslog_enable' => true,
+ ],
+ $config
+ );
+
+ return [
+ # setup unattended upgrades
+ (new Task())->setModule(new AptModule([
+ 'package' => 'unattended-upgrades',
+ 'updateCache' => true,
+ ])),
+ (new Task())->setModule(new TemplateModule([
+ 'src' => __DIR__ . '/unattended-upgrades/auto-upgrades.twig',
+ 'dest' => '/etc/apt/apt.conf.d/20auto-upgrades',
+ 'vars' => $config,
+ 'owner' => 'root',
+ 'group' => 'root',
+ 'mode' => 0644,
+ ])),
+ (new Task())->setModule(new TemplateModule([
+ 'src' => __DIR__ . '/unattended-upgrades/unattended-upgrades.twig',
+ 'dest' => '/etc/apt/apt.conf.d/50unattended-upgrades',
+ 'vars' => $config,
+ 'owner' => 'root',
+ 'group' => 'root',
+ 'mode' => 0644,
+ ])),
+
+ # setup user
+ (new Task())->setModule(new AptModule([
+ 'package' => 'zsh',
+ ])),
+ (new Task())->setModule(new UserModule([
+ 'username' => $config['username'],
+ 'password' => $config['password'],
+ 'groups' => ['sudo'],
+ 'append' => true,
+ 'shell' => '/bin/zsh',
+ ])),
+ (new Task())->setModule(new CopyModule([
+ 'src' => '~/.ssh',
+ 'dest' => '/home/' . $config['username'],
+ 'owner' => $config['username'],
+ 'group' => $config['username'],
+ 'remoteSrc' => true,
+ ])),
+ (new Task())->setModule(new GitModule([
+ 'repo' => 'https://github.com/ohmyzsh/ohmyzsh.git',
+ 'dest' => "/home/$config[username]/.oh-my-zsh",
+ 'owner' => $config['username'],
+ 'group' => $config['username'],
+ ])),
+ (new Task())->setModule(new CopyModule([
+ 'src' => "/home/$config[username]/.oh-my-zsh/templates/zshrc.zsh-template",
+ 'dest' => "/home/$config[username]/.zshrc",
+ 'owner' => $config['username'],
+ 'group' => $config['username'],
+ 'remoteSrc' => true,
+ ])),
+
+ # setup firewall
+ (new Task())->setModule(new UfwModule([
+ 'rule' => 'allow',
+ 'name' => 'OpenSSH',
+ 'state' => State::ENABLED,
+ ])),
+ ];
+ }
+}
diff --git a/src/unattended-upgrades/auto-upgrades.twig b/src/unattended-upgrades/auto-upgrades.twig
new file mode 100644
index 0000000..388a028
--- /dev/null
+++ b/src/unattended-upgrades/auto-upgrades.twig
@@ -0,0 +1,25 @@
+APT::Periodic::Unattended-Upgrade "1";
+
+{% if unattended_update_package_list is defined %}
+APT::Periodic::Update-Package-Lists "{{unattended_update_package_list}}";
+{% endif %}
+
+{% if unattended_download_upgradeable is defined %}
+APT::Periodic::Download-Upgradeable-Packages "{{unattended_download_upgradeable}}";
+{% endif %}
+
+{% if unattended_autoclean_interval is defined %}
+APT::Periodic::AutocleanInterval "{{unattended_autoclean_interval}}";
+{% endif %}
+
+{% if unattended_clean_interval is defined %}
+APT::Periodic::CleanInterval "{{unattended_clean_interval}}";
+{% endif %}
+
+{% if unattended_verbose is defined %}
+APT::Periodic::Verbose "{{unattended_verbose}}";
+{% endif %}
+
+{% if unattended_random_sleep is defined %}
+APT::Periodic::RandomSleep "{{unattended_random_sleep}}";
+{% endif %}
diff --git a/src/unattended-upgrades/unattended-upgrades.php b/src/unattended-upgrades/unattended-upgrades.php
new file mode 100644
index 0000000..1c3f73c
--- /dev/null
+++ b/src/unattended-upgrades/unattended-upgrades.php
@@ -0,0 +1,140 @@
+<?php
+
+return [
+ # Cache update time for apt module
+ 'unattended_cache_valid_time' => 3600,
+
+ #Unattended-Upgrade::Origins-Pattern
+ # Automatically upgrade packages from these origin patterns
+ # e.g.: 'o=Debian,a=stable', 'o=Debian,a=stable-updates'
+ #
+ # Left unset, distribution-specific defaults will be used through
+ # __unattended_origins_patterns variable only if this variable
+ # is not provided externally
+ # REFS https://github.com/ansible/ansible/issues/8121
+ #'unattended_origins_patterns' => [],
+
+ #Unattended-Upgrade::Package-Blacklist
+ # List of packages to not update
+ 'unattended_package_blacklist' => [],
+
+ #Unattended-Upgrade::AutoFixInterruptedDpkg
+ # On a unclean dpkg exit unattended-upgrades will run
+ # dpkg --force-confold --configure -a
+ # The default is true, to ensure updates keep getting installed
+ 'unattended_autofix_interrupted_dpkg' => true,
+
+ #Unattended-Upgrade::MinimalSteps
+ # Split the upgrade into the smallest possible chunks so that
+ # they can be interrupted with SIGUSR1. This makes the upgrade
+ # a bit slower but it has the benefit that shutdown while a upgrade
+ # is running is possible (with a small delay)
+ 'unattended_minimal_steps' => true,
+
+ #Unattended-Upgrade::InstallOnShutdown
+ # Install all unattended-upgrades when the machine is shuting down
+ # instead of doing it in the background while the machine is running
+ # This will (obviously) make shutdown slower
+ 'unattended_install_on_shutdown' => false,
+
+ #Unattended-Upgrade::Mail
+ # Send email to this address for problems or packages upgrades
+ # If empty or unset then no email is sent, make sure that you
+ # have a working mail setup on your system. A package that provides
+ # 'mailx' must be installed.
+ 'unattended_mail' => false,
+
+ #Unattended-Upgrade::MailOnlyOnError
+ # Set this value to "true" to get emails only on errors. Default
+ # is to always send a mail if Unattended-Upgrade::Mail is set
+ 'unattended_mail_only_on_error' => false,
+
+ #Unattended-Upgrade::Remove-Unused-Dependencies
+ # Do automatic removal of all unused dependencies after the upgrade
+ # (equivalent to apt-get autoremove)
+ 'unattended_remove_unused_dependencies' => false,
+
+ #Unattended-Upgrade::Remove-New-Unused-Dependencies
+ # Remove any new unused dependencies after the upgrade
+ 'unattended_remove_new_unused_dependencies' => true,
+
+ #Unattended-Upgrade::Automatic-Reboot
+ # Automatically reboot *WITHOUT CONFIRMATION* if a
+ # the file /var/run/reboot-required is found after the upgrade
+ 'unattended_automatic_reboot' => false,
+
+ #Unattended-Upgrade::Automatic-Reboot-Time
+ # If automatic reboot is enabled and needed, reboot at the specific
+ # time instead of immediately
+ 'unattended_automatic_reboot_time' => false,
+
+ #Unattended-Upgrade::IgnoreAppsRequireRestart
+ # Do upgrade application even if it requires restart after upgrade
+ # I.e. "XB-Upgrade-Requires: app-restart" is set in the debian/control file
+ 'unattended_ignore_apps_require_restart' => false,
+
+ #Unattended-Upgrade::SyslogEnable
+ # Write events to syslog, which is useful in environments where syslog
+ # messages are sent to a central store.
+ 'unattended_syslog_enable' => false,
+
+ #Unattended-Upgrade::SyslogFacility
+ # Write events to the specified syslog facility, or the daemon facility if
+ # not specified. Requires the Unattended-Upgrade::SyslogEnable option to be
+ # set to true.
+ #'unattended_syslog_facility' => 'daemon',
+
+ ### APT::Periodic configuration
+ # Snatched from /usr/lib/apt/apt.systemd.daily
+
+ #APT::Periodic::Update-Package-Lists "0";
+ # - Do "apt-get update" automatically every n-days (0=disable)
+ 'unattended_update_package_list' => 1,
+
+ #APT::Periodic::Download-Upgradeable-Packages "0";
+ # - Do "apt-get upgrade --download-only" every n-days (0=disable)
+ #'unattended_download_upgradeable' => 0,
+
+ #APT::Periodic::AutocleanInterval "0";
+ # - Do "apt-get autoclean" every n-days (0=disable)
+ 'unattended_autoclean_interval' => 7,
+
+ #APT::Periodic::CleanInterval "0";
+ # - Do "apt-get clean" every n-days (0=disable)
+ #'unattended_clean_interval' => 0,
+
+ #APT::Periodic::Verbose "0";
+ # - Send report mail to root
+ # 0: no report (or null string)
+ # 1: progress report (actually any string)
+ # 2: + command outputs (remove -qq, remove 2>/dev/null, add -d)
+ # 3: + trace on
+ #'unattended_verbose' => 0,
+
+ ## Cron systems only
+
+ #APT::Periodic::RandomSleep
+ # When the apt job starts, it will sleep for a random period between 0
+ # and APT::Periodic::RandomSleep seconds
+ # The default value is "1800" so that the script will stall for up to 30
+ # minutes (1800 seconds) so that the mirror servers are not crushed by
+ # everyone running their updates all at the same time
+ # Kept undefined to allow default (1800)
+ #'unattended_random_sleep' => 0,
+
+ #Dpkg::Options
+ # Provide dpkg options that take effect during unattended upgrades.
+ # By default no flags are appended. Configuration file changes can
+ # block installation of certain packages. Passing the flags
+ # "--force-confdef" and "--force-confold" will ensure updates are applied
+ # and old configuration files are preserved.
+ 'unattended_dpkg_options' => [],
+
+ # 'unattended_dpkg_options' => [
+ # '--force-confdef',
+ # '--force-confold',
+ # ],
+
+ # Use apt bandwidth limit feature, this example limits the download speed to 70kb/sec
+ #'unattended_dl_limit' => 70,
+];
diff --git a/src/unattended-upgrades/unattended-upgrades.twig b/src/unattended-upgrades/unattended-upgrades.twig
new file mode 100644
index 0000000..0796f6b
--- /dev/null
+++ b/src/unattended-upgrades/unattended-upgrades.twig
@@ -0,0 +1,117 @@
+// Unattended-Upgrade::Origins-Pattern controls which packages are
+// upgraded.
+Unattended-Upgrade::Origins-Pattern {
+{% if unattended_origins_patterns is defined %}
+{% for origin in unattended_origins_patterns %}
+ "{{ origin }}";
+{% endfor %}
+{% endif %}
+};
+
+// List of packages to not update (regexp are supported)
+Unattended-Upgrade::Package-Blacklist {
+{% for package in unattended_package_blacklist %}
+ "{{ package }}";
+{% endfor %}
+};
+
+{% if not unattended_autofix_interrupted_dpkg %}
+// This option allows you to control if on a unclean dpkg exit
+// unattended-upgrades will automatically run
+// dpkg --force-confold --configure -a
+// The default is true, to ensure updates keep getting installed
+Unattended-Upgrade::AutoFixInterruptedDpkg "false";
+{% endif %}
+
+// Split the upgrade into the smallest possible chunks so that
+// they can be interrupted with SIGUSR1. This makes the upgrade
+// a bit slower but it has the benefit that shutdown while a upgrade
+// is running is possible (with a small delay)
+Unattended-Upgrade::MinimalSteps "{{ unattended_minimal_steps | lower }}";
+
+{% if unattended_install_on_shutdown %}
+// Install all unattended-upgrades when the machine is shuting down
+// instead of doing it in the background while the machine is running
+// This will (obviously) make shutdown slower
+Unattended-Upgrade::InstallOnShutdown "true";
+{% endif %}
+
+{% if unattended_mail %}
+// Send email to this address for problems or packages upgrades
+// If empty or unset then no email is sent, make sure that you
+// have a working mail setup on your system. A package that provides
+// 'mailx' must be installed.
+Unattended-Upgrade::Mail "{{ unattended_mail }}";
+{% endif %}
+
+{% if unattended_mail_only_on_error %}
+// Set this value to "true" to get emails only on errors. Default
+// is to always send a mail if Unattended-Upgrade::Mail is set
+Unattended-Upgrade::MailOnlyOnError "true";
+{% endif %}
+
+{% if unattended_remove_unused_dependencies %}
+// Do automatic removal of all unused dependencies after the upgrade
+// (equivalent to apt-get autoremove)
+Unattended-Upgrade::Remove-Unused-Dependencies "true";
+{% endif %}
+
+{% if not unattended_remove_new_unused_dependencies %}
+// Do automatic removal of new unused dependencies after the upgrade
+Unattended-Upgrade::Remove-New-Unused-Dependencies "false";
+{% endif %}
+
+{% if unattended_automatic_reboot %}
+// Automatically reboot *WITHOUT CONFIRMATION* if a
+// the file /var/run/reboot-required is found after the upgrade
+Unattended-Upgrade::Automatic-Reboot "true";
+{% endif %}
+
+{% if unattended_automatic_reboot_time %}
+// If automatic reboot is enabled and needed, reboot at the specific
+// time instead of immediately
+// Default: "now"
+Unattended-Upgrade::Automatic-Reboot-Time "{{ unattended_automatic_reboot_time }}";
+{% endif %}
+
+{% if unattended_update_days is defined %}
+// Set the days of the week that updates should be applied. The days can be specified
+// as localized abbreviated or full names. Or as integers where "0" is Sunday, "1" is
+// Monday etc.
+// Example - apply updates only on Monday and Friday:
+// {"Mon";"Fri"};
+Unattended-Upgrade::Update-Days {{ unattended_update_days }};
+{% endif %}
+
+{% if unattended_ignore_apps_require_restart %}
+// Do upgrade application even if it requires restart after upgrade
+// I.e. "XB-Upgrade-Requires: app-restart" is set in the debian/control file
+Unattended-Upgrade::IgnoreAppsRequireRestart "true";
+{% endif %}
+
+{% if unattended_syslog_enable %}
+// Write events to syslog, which is useful in environments where syslog
+// messages are sent to a central store.
+Unattended-Upgrade::SyslogEnable "{{ unattended_syslog_enable }}";
+{% if unattended_syslog_facility is defined %}
+// Write events to the specified syslog facility, or the daemon facility
+// if not specified. Requires the Unattended-Upgrade::SyslogEnable option
+// to be set to true.
+Unattended-Upgrade::SyslogFacility "{{ unattended_syslog_facility }}";
+{% endif %}
+{% endif %}
+
+{% if unattended_dpkg_options %}
+// Append options for governing dpkg behavior, e.g. --force-confdef.
+Dpkg::Options {
+{% for dpkg_option in unattended_dpkg_options %}
+ "{{ dpkg_option }}";
+{% endfor %}
+};
+{% endif %}
+
+{% if unattended_dl_limit is defined %}
+// Use apt bandwidth limit feature, this example limits the download
+// speed to 70kb/sec
+Acquire::http::Dl-Limit "{{ unattended_dl_limit }}";
+{% endif %}
diff --git a/test/Vagrantfile b/test/Vagrantfile
new file mode 100644
index 0000000..a69333e
--- /dev/null
+++ b/test/Vagrantfile
@@ -0,0 +1,70 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# All Vagrant configuration is done below. The "2" in Vagrant.configure
+# configures the configuration version (we support older styles for
+# backwards compatibility). Please don't change it unless you know what
+# you're doing.
+Vagrant.configure("2") do |config|
+ # The most common configuration options are documented and commented below.
+ # For a complete reference, please see the online documentation at
+ # https://docs.vagrantup.com.
+
+ # Every Vagrant development environment requires a box. You can search for
+ # boxes at https://vagrantcloud.com/search.
+ config.vm.box = "bento/ubuntu-20.04"
+
+ # Disable automatic box update checking. If you disable this, then
+ # boxes will only be checked for updates when the user runs
+ # `vagrant box outdated`. This is not recommended.
+ # config.vm.box_check_update = false
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine. In the example below,
+ # accessing "localhost:8080" will access port 80 on the guest machine.
+ # NOTE: This will enable public access to the opened port
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
+
+ # Create a forwarded port mapping which allows access to a specific port
+ # within the machine from a port on the host machine and only allow access
+ # via 127.0.0.1 to disable public access
+ # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
+
+ # Create a private network, which allows host-only access to the machine
+ # using a specific IP.
+ config.vm.network "private_network", ip: "192.168.33.10"
+
+ # Create a public network, which generally matched to bridged network.
+ # Bridged networks make the machine appear as another physical device on
+ # your network.
+ # config.vm.network "public_network"
+
+ # Share an additional folder to the guest VM. The first argument is
+ # the path on the host to the actual folder. The second argument is
+ # the path on the guest to mount the folder. And the optional third
+ # argument is a set of non-required options.
+ # config.vm.synced_folder "../data", "/vagrant_data"
+
+ # Provider-specific configuration so you can fine-tune various
+ # backing providers for Vagrant. These expose provider-specific options.
+ # Example for VirtualBox:
+ #
+ # config.vm.provider "virtualbox" do |vb|
+ # # Display the VirtualBox GUI when booting the machine
+ # vb.gui = true
+ #
+ # # Customize the amount of memory on the VM:
+ # vb.memory = "1024"
+ # end
+ #
+ # View the documentation for the provider you are using for more
+ # information on available options.
+
+ # Enable provisioning with a shell script. Additional provisioners such as
+ # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
+ # documentation for more information about their specific syntax and use.
+ # config.vm.provision "shell", inline: <<-SHELL
+ # apt-get update
+ # apt-get install -y apache2
+ # SHELL
+end
diff --git a/test/config.php b/test/config.php
new file mode 100644
index 0000000..6cc5ecc
--- /dev/null
+++ b/test/config.php
@@ -0,0 +1,17 @@
+<?php
+
+include dirname(__DIR__) . '/vendor/autoload.php';
+
+return [
+ 'host' => 'vagrant',
+ 'user' => 'vagrant',
+ 'private_key_file' => __DIR__ . '/.vagrant/machines/default/virtualbox/private_key',
+
+ 'tasks' => [
+ ...(new \Dweipert\DevOps\BaseServerSetup\BaseServerSetup())([
+ 'username' => 'dweipert',
+ 'password' => '1234',
+ 'mail' => 'test@example.org',
+ ]),
+ ],
+];