aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDermot Bradley <dermot_bradley@yahoo.com>2020-06-29 19:45:42 +0100
committerLeo <thinkabit.ukim@gmail.com>2020-06-29 20:46:31 +0000
commita9cf7ee19c96351389170e2d22c58e4d64fa21a0 (patch)
treeaaaa8bd386dd68cac149d2142935c7c5fc72683a
parent6907aa6272c7d980015512086c34274a8f906789 (diff)
downloadaports-a9cf7ee19c96351389170e2d22c58e4d64fa21a0.tar.gz
aports-a9cf7ee19c96351389170e2d22c58e4d64fa21a0.tar.bz2
aports-a9cf7ee19c96351389170e2d22c58e4d64fa21a0.tar.xz
testing/cloud-init: upgrade to 20.2
Updated to 20.2 release. Adds Alpine support to ca_certs, ntp, power_state, and resolv_conf modules. Created apk_configure module. Improved networking and user/group functionality. Become package maintainer. I have signed upstream CLA and am working on upstreaming these changes.
-rw-r--r--testing/cloud-init/01-add-distro-alpine.patch (renamed from testing/cloud-init/add_distro-alpine.patch)0
-rw-r--r--testing/cloud-init/02-add-to-util.patch11
-rw-r--r--testing/cloud-init/03-add-to-cloud-cfg-template.patch90
-rw-r--r--testing/cloud-init/04-add-to-render-cloudcfg.patch11
-rw-r--r--testing/cloud-init/05-add-ca_certs-module-support.patch80
-rw-r--r--testing/cloud-init/06-add-ntp-module-support.patch24
-rw-r--r--testing/cloud-init/07-add-power_state-module-support.patch97
-rw-r--r--testing/cloud-init/08-add-resolv_conf-module-support.patch20
-rw-r--r--testing/cloud-init/APKBUILD94
-rw-r--r--testing/cloud-init/alpine.py104
-rw-r--r--testing/cloud-init/cc_apk_configure.py148
-rw-r--r--testing/cloud-init/chrony.conf.alpine.tmpl38
-rw-r--r--testing/cloud-init/cloud.cfg76
-rw-r--r--testing/cloud-init/hosts.alpine.tmpl19
-rw-r--r--testing/cloud-init/interfaces11
-rw-r--r--testing/cloud-init/ntp.conf.alpine.tmpl10
16 files changed, 643 insertions, 190 deletions
diff --git a/testing/cloud-init/add_distro-alpine.patch b/testing/cloud-init/01-add-distro-alpine.patch
index ed27e1daa3..ed27e1daa3 100644
--- a/testing/cloud-init/add_distro-alpine.patch
+++ b/testing/cloud-init/01-add-distro-alpine.patch
diff --git a/testing/cloud-init/02-add-to-util.patch b/testing/cloud-init/02-add-to-util.patch
new file mode 100644
index 0000000000..5b6d35fe54
--- /dev/null
+++ b/testing/cloud-init/02-add-to-util.patch
@@ -0,0 +1,11 @@
+--- a/cloudinit/util.py
++++ b/cloudinit/util.py
+@@ -649,7 +649,7 @@
+ if system == "linux":
+ linux_dist = info['dist'][0].lower()
+ if linux_dist in (
+- 'arch', 'centos', 'debian', 'fedora', 'rhel', 'suse'):
++ 'alpine', 'arch', 'centos', 'debian', 'fedora', 'rhel', 'suse'):
+ var = linux_dist
+ elif linux_dist in ('ubuntu', 'linuxmint', 'mint'):
+ var = 'ubuntu'
diff --git a/testing/cloud-init/03-add-to-cloud-cfg-template.patch b/testing/cloud-init/03-add-to-cloud-cfg-template.patch
new file mode 100644
index 0000000000..536050bcc4
--- /dev/null
+++ b/testing/cloud-init/03-add-to-cloud-cfg-template.patch
@@ -0,0 +1,90 @@
+--- a/config/cloud.cfg.tmpl
++++ b/config/cloud.cfg.tmpl
+@@ -21,7 +21,7 @@
+ disable_root: true
+ {% endif %}
+
+-{% if variant in ["amazon", "centos", "fedora", "rhel"] %}
++{% if variant in ["alpine", "amazon", "centos", "fedora", "rhel"] %}
+ mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
+ {% if variant == "amazon" %}
+ resize_rootfs: noblock
+@@ -72,6 +72,9 @@
+ - update_hostname
+ {% if variant not in ["freebsd", "netbsd"] %}
+ - update_etc_hosts
++{% if variant in ["alpine"] %}
++ - resolv_conf
++{% endif %}
+ - ca-certs
+ - rsyslog
+ {% endif %}
+@@ -104,6 +107,9 @@
+ {% if variant in ["suse"] %}
+ - zypper-add-repo
+ {% endif %}
++{% if variant in ["alpine"] %}
++ - apk-configure
++{% endif %}
+ {% if variant not in ["freebsd", "netbsd"] %}
+ - ntp
+ {% endif %}
+@@ -147,7 +153,7 @@
+ # (not accessible to handlers/transforms)
+ system_info:
+ # This will affect which distro class gets used
+-{% if variant in ["amazon", "arch", "centos", "debian", "fedora", "freebsd", "netbsd", "openbsd", "rhel", "suse", "ubuntu"] %}
++{% if variant in ["alpine", "amazon", "arch", "centos", "debian", "fedora", "freebsd", "netbsd", "openbsd", "rhel", "suse", "ubuntu"] %}
+ distro: {{ variant }}
+ {% else %}
+ # Unknown/fallback distro.
+@@ -169,9 +175,9 @@
+ ntp_client: auto
+ # Other config here will be given to the distro class and/or path classes
+ paths:
+- cloud_dir: /var/lib/cloud/
+- templates_dir: /etc/cloud/templates/
+- upstart_dir: /etc/init/
++ cloud_dir: /var/lib/cloud/
++ templates_dir: /etc/cloud/templates/
++ upstart_dir: /etc/init/
+ package_mirrors:
+ - arches: [i386, amd64]
+ failsafe:
+@@ -198,8 +204,8 @@
+ primary: http://ports.ubuntu.com/ubuntu-ports
+ security: http://ports.ubuntu.com/ubuntu-ports
+ ssh_svcname: ssh
+-{% elif variant in ["amazon", "arch", "centos", "fedora", "rhel", "suse"] %}
+- # Default user name + that default users groups (if added/used)
++{% elif variant in ["alpine", "amazon", "arch", "centos", "fedora", "rhel", "suse"] %}
++ # Default user name + that default user's groups (if added/used)
+ default_user:
+ {% if variant == "amazon" %}
+ name: ec2-user
+@@ -212,17 +218,23 @@
+ {% endif %}
+ {% if variant == "suse" %}
+ groups: [cdrom, users]
++{% elif variant == "alpine" %}
++ groups: [adm, sudo]
+ {% elif variant == "arch" %}
+ groups: [wheel, users]
+ {% else %}
+ groups: [wheel, adm, systemd-journal]
+ {% endif %}
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
++{% if variant == "alpine" %}
++ shell: /bin/ash
++{% else %}
+ shell: /bin/bash
++{% endif %}
+ # Other config here will be given to the distro class and/or path classes
+ paths:
+- cloud_dir: /var/lib/cloud/
+- templates_dir: /etc/cloud/templates/
++ cloud_dir: /var/lib/cloud/
++ templates_dir: /etc/cloud/templates/
+ ssh_svcname: sshd
+ {% elif variant in ["freebsd"] %}
+ # Default user name + that default users groups (if added/used)
diff --git a/testing/cloud-init/04-add-to-render-cloudcfg.patch b/testing/cloud-init/04-add-to-render-cloudcfg.patch
new file mode 100644
index 0000000000..3e8bdb8a69
--- /dev/null
+++ b/testing/cloud-init/04-add-to-render-cloudcfg.patch
@@ -0,0 +1,11 @@
+--- a/tools/render-cloudcfg
++++ b/tools/render-cloudcfg
+@@ -4,7 +4,7 @@
+ import os
+ import sys
+
+-VARIANTS = ["amazon", "arch", "centos", "debian", "fedora", "freebsd",
++VARIANTS = ["alpine", "amazon", "arch", "centos", "debian", "fedora", "freebsd",
+ "netbsd", "openbsd", "rhel", "suse", "ubuntu", "unknown"]
+
+
diff --git a/testing/cloud-init/05-add-ca_certs-module-support.patch b/testing/cloud-init/05-add-ca_certs-module-support.patch
new file mode 100644
index 0000000000..8025101921
--- /dev/null
+++ b/testing/cloud-init/05-add-ca_certs-module-support.patch
@@ -0,0 +1,80 @@
+--- a/cloudinit/config/cc_ca_certs.py
++++ b/cloudinit/config/cc_ca_certs.py
+@@ -16,11 +16,15 @@
+ certificates must be specified using valid yaml. in order to specify a
+ multiline certificate, the yaml multiline list syntax must be used
+
++.. note::
++ For Alpine Linux this module works with the ca-certificates package
++ but not with the ca-certificates-bundle package.
++
+ **Internal name:** ``cc_ca_certs``
+
+ **Module frequency:** per instance
+
+-**Supported distros:** ubuntu, debian
++**Supported distros:** alpine, debian, ubuntu
+
+ **Config keys**::
+
+@@ -44,7 +48,7 @@
+ CA_CERT_SYSTEM_PATH = "/etc/ssl/certs/"
+ CA_CERT_FULL_PATH = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME)
+
+-distros = ['ubuntu', 'debian']
++distros = ['alpine', 'debian', 'ubuntu']
+
+
+ def update_ca_certs():
+@@ -66,17 +70,23 @@
+ cert_file_contents = "\n".join([str(c) for c in certs])
+ util.write_file(CA_CERT_FULL_PATH, cert_file_contents, mode=0o644)
+
+- # Append cert filename to CA_CERT_CONFIG file.
+- # We have to strip the content because blank lines in the file
+- # causes subsequent entries to be ignored. (LP: #1077020)
+- orig = util.load_file(CA_CERT_CONFIG)
+- cur_cont = '\n'.join([line for line in orig.splitlines()
++ if os.stat(CA_CERT_CONFIG).st_size == 0:
++ # If the CA_CERT_CONFIG file is empty (i.e. all existing
++ # certificates have been deleted) then simply output a single
++ # line with the cloud-init cert filename.
++ out = "%s\n" % CA_CERT_FILENAME
++ else:
++ # Append cert filename to CA_CERT_CONFIG file.
++ # We have to strip the content because blank lines in the file
++ # causes subsequent entries to be ignored. (LP: #1077020)
++ orig = util.load_file(CA_CERT_CONFIG)
++ cur_cont = '\n'.join([line for line in orig.splitlines()
+ if line != CA_CERT_FILENAME])
+- out = "%s\n%s\n" % (cur_cont.rstrip(), CA_CERT_FILENAME)
++ out = "%s\n%s\n" % (cur_cont.rstrip(), CA_CERT_FILENAME)
+ util.write_file(CA_CERT_CONFIG, out, omode="wb")
+
+
+-def remove_default_ca_certs():
++def remove_default_ca_certs(distro):
+ """
+ Removes all default trusted CA certificates from the system. To actually
+ apply the change you must also call L{update_ca_certs}.
+@@ -84,8 +94,9 @@
+ util.delete_dir_contents(CA_CERT_PATH)
+ util.delete_dir_contents(CA_CERT_SYSTEM_PATH)
+ util.write_file(CA_CERT_CONFIG, "", mode=0o644)
+- debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no"
+- util.subp(('debconf-set-selections', '-'), debconf_sel)
++ if distro != 'alpine':
++ debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no"
++ util.subp(('debconf-set-selections', '-'), debconf_sel)
+
+
+ def handle(name, cfg, _cloud, log, _args):
+@@ -110,7 +121,7 @@
+ # default trusted CA certs first.
+ if ca_cert_cfg.get("remove-defaults", False):
+ log.debug("Removing default certificates")
+- remove_default_ca_certs()
++ remove_default_ca_certs(_cloud.distro.name)
+
+ # If we are given any new trusted CA certs to add, add them.
+ if "trusted" in ca_cert_cfg:
diff --git a/testing/cloud-init/06-add-ntp-module-support.patch b/testing/cloud-init/06-add-ntp-module-support.patch
new file mode 100644
index 0000000000..7a253a682f
--- /dev/null
+++ b/testing/cloud-init/06-add-ntp-module-support.patch
@@ -0,0 +1,24 @@
+--- a/cloudinit/config/cc_ntp.py
++++ b/cloudinit/config/cc_ntp.py
+@@ -23,7 +23,7 @@
+ frequency = PER_INSTANCE
+ NTP_CONF = '/etc/ntp.conf'
+ NR_POOL_SERVERS = 4
+-distros = ['centos', 'debian', 'fedora', 'opensuse', 'rhel', 'sles', 'ubuntu']
++distros = ['alpine', 'centos', 'debian', 'fedora', 'opensuse', 'rhel', 'sles', 'ubuntu']
+
+ NTP_CLIENT_CONFIG = {
+ 'chrony': {
+@@ -62,6 +62,12 @@
+
+ # This is Distro-specific configuration overrides of the base config
+ DISTRO_CLIENT_CONFIG = {
++ 'alpine': {
++ 'chrony': {
++ 'confpath': '/etc/chrony/chrony.conf',
++ 'service_name': 'chronyd',
++ },
++ },
+ 'debian': {
+ 'chrony': {
+ 'confpath': '/etc/chrony/chrony.conf',
diff --git a/testing/cloud-init/07-add-power_state-module-support.patch b/testing/cloud-init/07-add-power_state-module-support.patch
new file mode 100644
index 0000000000..976bd11f8a
--- /dev/null
+++ b/testing/cloud-init/07-add-power_state-module-support.patch
@@ -0,0 +1,97 @@
+--- a/cloudinit/config/cc_power_state_change.py
++++ b/cloudinit/config/cc_power_state_change.py
+@@ -33,6 +33,10 @@
+ ``condition`` key is omitted or the command specified by the ``condition``
+ key returns 0.
+
++.. note::
++ With Alpine Linux any message value specified is ignored as Alpine's halt,
++ poweroff, and reboot commands do not support broadcasting a message.
++
+ **Internal name:** ``cc_power_state_change``
+
+ **Module frequency:** per instance
+@@ -113,7 +117,7 @@
+
+ def handle(_name, cfg, _cloud, log, _args):
+ try:
+- (args, timeout, condition) = load_power_state(cfg)
++ (args, timeout, condition) = load_power_state(cfg, _cloud.distro.name)
+ if args is None:
+ log.debug("no power_state provided. doing nothing")
+ return
+@@ -140,7 +144,7 @@
+ condition, execmd, [args, devnull_fp])
+
+
+-def load_power_state(cfg):
++def load_power_state(cfg, distro):
+ # returns a tuple of shutdown_command, timeout
+ # shutdown_command is None if no config found
+ pstate = cfg.get('power_state')
+@@ -151,7 +155,10 @@
+ if not isinstance(pstate, dict):
+ raise TypeError("power_state is not a dict.")
+
+- opt_map = {'halt': '-H', 'poweroff': '-P', 'reboot': '-r'}
++ if distro == 'alpine':
++ opt_map = {'halt': '', 'poweroff': '', 'reboot': ''}
++ else:
++ opt_map = {'halt': '-H', 'poweroff': '-P', 'reboot': '-r'}
+
+ mode = pstate.get("mode")
+ if mode not in opt_map:
+@@ -160,20 +167,39 @@
+ (','.join(opt_map.keys()), mode))
+
+ delay = pstate.get("delay", "now")
+- # convert integer 30 or string '30' to '+30'
+- try:
+- delay = "+%s" % int(delay)
+- except ValueError:
+- pass
+-
+- if delay != "now" and not re.match(r"\+[0-9]+", delay):
+- raise TypeError(
+- "power_state[delay] must be 'now' or '+m' (minutes)."
+- " found '%s'." % delay)
+-
+- args = ["shutdown", opt_map[mode], delay]
+- if pstate.get("message"):
+- args.append(pstate.get("message"))
++ if distro == 'alpine':
++ # Convert integer 30 or string '30' to '1800' (seconds) as Alpine's
++ # halt/poweroff/reboot commands take seconds as param with no "+"
++ try:
++ delay = "%s" % int( int(delay) * 60)
++ except ValueError:
++ pass
++
++ if delay != "now" and not re.match(r"[0-9]", delay):
++ raise TypeError(
++ "power_state[delay] must be 'now' or '+m' (minutes)."
++ " found '%s'." % delay)
++
++ if delay == "now":
++ # Alpine's halt/poweroff/reboot don't understand "now"
++ delay = "0"
++
++ args = [mode, "-d", delay]
++ else:
++ # convert integer 30 or string '30' to '+30'
++ try:
++ delay = "+%s" % int(delay)
++ except ValueError:
++ pass
++
++ if delay != "now" and not re.match(r"\+[0-9]+", delay):
++ raise TypeError(
++ "power_state[delay] must be 'now' or '+m' (minutes)."
++ " found '%s'." % delay)
++
++ args = ["shutdown", opt_map[mode], delay]
++ if pstate.get("message"):
++ args.append(pstate.get("message"))
+
+ try:
+ timeout = float(pstate.get('timeout', 30.0))
diff --git a/testing/cloud-init/08-add-resolv_conf-module-support.patch b/testing/cloud-init/08-add-resolv_conf-module-support.patch
new file mode 100644
index 0000000000..dee21ef2f4
--- /dev/null
+++ b/testing/cloud-init/08-add-resolv_conf-module-support.patch
@@ -0,0 +1,20 @@
+--- a/cloudinit/config/cc_resolv_conf.py
++++ b/cloudinit/config/cc_resolv_conf.py
+@@ -30,7 +30,7 @@
+
+ **Module frequency:** per instance
+
+-**Supported distros:** fedora, rhel, sles
++**Supported distros:** alpine, fedora, rhel, sles
+
+ **Config keys**::
+
+@@ -55,7 +55,7 @@
+
+ frequency = PER_INSTANCE
+
+-distros = ['fedora', 'opensuse', 'rhel', 'sles']
++distros = ['alpine', 'fedora', 'opensuse', 'rhel', 'sles']
+
+
+ def generate_resolv_conf(template_fn, params, target_fname="/etc/resolv.conf"):
diff --git a/testing/cloud-init/APKBUILD b/testing/cloud-init/APKBUILD
index 45512eb0f9..e2601a7403 100644
--- a/testing/cloud-init/APKBUILD
+++ b/testing/cloud-init/APKBUILD
@@ -1,27 +1,45 @@
# Contributor: Matt Dainty <matt+alpine@bodgit-n-scarper.com>
-# Maintainer:
+# Contributor: Dermot Bradley <dermot_bradley@yahoo.com>
+# Maintainer: Dermot Bradley <dermot_bradley@yahoo.com>
pkgname=cloud-init
-pkgver=18.5
-pkgrel=3
+pkgver=20.2
+pkgrel=0
pkgdesc="Cloud instance init scripts"
url="https://cloud-init.io"
arch="noarch"
license="Apache-2.0 OR GPL-3.0-only"
-depends="e2fsprogs-extra python3 py3-configobj py3-jinja2 py3-jsonpatch py3-jsonschema
- py3-oauthlib py3-requests py3-serial py3-six py3-yaml"
+depends="blkid e2fsprogs-extra ifupdown python3 py3-configobj py3-jinja2
+ py3-jsonpatch py3-jsonschema py3-oauthlib py3-requests py3-serial
+ py3-six py3-yaml shadow sudo"
makedepends="py3-setuptools"
-subpackages="$pkgname-doc $pkgname-bash-completion:bashcomp:noarch $pkgname-openrc"
-source="https://launchpad.net/cloud-init/trunk/18.5/+download/cloud-init-$pkgver.tar.gz
- add_distro-alpine.patch
- cloud.cfg
- hosts.alpine.tmpl
+subpackages="$pkgname-doc $pkgname-bash-completion $pkgname-openrc"
+source="https://launchpad.net/cloud-init/trunk/$pkgver/+download/cloud-init-$pkgver.tar.gz
+ 01-add-distro-alpine.patch
+ 02-add-to-util.patch
+ 03-add-to-cloud-cfg-template.patch
+ 04-add-to-render-cloudcfg.patch
+ 05-add-ca_certs-module-support.patch
+ 06-add-ntp-module-support.patch
+ 07-add-power_state-module-support.patch
+ 08-add-resolv_conf-module-support.patch
alpine.py
+ cc_apk_configure.py
+ chrony.conf.alpine.tmpl
+ hosts.alpine.tmpl
+ interfaces
+ ntp.conf.alpine.tmpl
"
+
prepare() {
default_prepare
- install -m644 "$srcdir"/alpine.py \
+ install -m644 \
+ "$srcdir"/alpine.py \
"$builddir"/cloudinit/distros/
+
+ install -m644 \
+ "$srcdir"/cc_apk_configure.py \
+ "$builddir"/cloudinit/config/
}
build() {
@@ -33,28 +51,46 @@ check() {
}
package() {
- python3 setup.py install --prefix=/usr --root="$pkgdir" --init-system=sysvinit_openrc
-
- install -m644 "$srcdir"/cloud.cfg \
- "$pkgdir"/etc/cloud/
+ python3 setup.py install \
+ --prefix=/usr --root="$pkgdir" --init-system=sysvinit_openrc
- install -m644 "$srcdir"/hosts.alpine.tmpl \
+ install -m644 \
+ "$srcdir"/*.tmpl \
"$pkgdir"/etc/cloud/templates/
- mkdir -p "$pkgdir"/usr/share/bash-completion
- mv "$pkgdir"/etc/bash_completion.d "$pkgdir"/usr/share/bash-completion/completions
-}
+ mkdir -p \
+ "$pkgdir"/etc/network
+ install -m644 \
+ "$srcdir"/interfaces \
+ "$pkgdir"/etc/network/
-bashcomp() {
- depends=""
- pkgdesc="Bash completions for $pkgname"
- install_if="$pkgname=$pkgver-r$pkgrel bash-completion"
+ # Delete non-Alpine distribution template files
+ for distro in \
+ debian fedora freebsd opensuse redhat rhel sles suse ubuntu
+ do
+ for file in \
+ "$(ls "$pkgdir"/etc/cloud/templates/*"$distro".tmpl)"
+ do
+ rm $file
+ done
+ done
- amove usr/share/bash-completion/completions
+ # Delete systemd template file
+ rm "$pkgdir"/etc/cloud/templates/timesyncd.conf.tmpl
}
-sha512sums="f89ee636922e33b5b2dcb5230763404fbeee148e28b8f61bf5b2f1f07000f960f9d38545dfb7bcbe9afb8253f77d66c94b39e9a159715b44a440a7cbe1fe1aeb cloud-init-18.5.tar.gz
-4ab37323e7662445af90ce2654199fe3080e256571e8e12b121ebde791b98e68d368b10c5f22b7e8840c0ba9593dd0a6e37ec60724cd0ae4c806944a826741e3 add_distro-alpine.patch
-7dd8c3a2050af5536154e77cc3913d34b7d85d02130ea9b9f5b54710f96cd22cb4c255af34f3c710a1319f9bd0f667441482695e9bad927026f952d0cf39de41 cloud.cfg
-813a67d446ee65f5ef5a45fe60bef4d0e404c5d1f9cb732bc0ec0b706a0274f4bc1e7f87e676da1ca9366c2f933163f620ee296ed783372869438dd8a928117b hosts.alpine.tmpl
-301e99d25cbe3607f6187ef477e15c8ffc356456117fcd662528194d880a989ba79622208eb84c27decf19060c3810c9ff11441d041c2061feced823e453acaf alpine.py"
+sha512sums="2b63d435b162b6db232121959dc2e5fa59c7cc8916fca3bccb637dd5e583931930f6b4e0a22b961ee71058f518a090c0a636da8147b999acdaa06cd2fc3ee51c cloud-init-20.2.tar.gz
+4ab37323e7662445af90ce2654199fe3080e256571e8e12b121ebde791b98e68d368b10c5f22b7e8840c0ba9593dd0a6e37ec60724cd0ae4c806944a826741e3 01-add-distro-alpine.patch
+5b6cba9da22c1b8d202170f215995abe22100251dee705219607cdadf32de498a3af56aab8324254f755ef0caa22f6a4e9fdcf8fc53dc4fde6757957a266405e 02-add-to-util.patch
+236862f50c841704750109a1e4fe985bec6501554d8da33e1103fe35795c2ee566ae8d6b79cc2ec09160ec614fa61c09f1a778dea85d0e5e1ecb487d5f0d7fa0 03-add-to-cloud-cfg-template.patch
+d92ea4aaf811a7338348054d8438051cf3f6a11e92b976f3b7c4d976f64de3144c97ec3c44a5691299eb499d0089b5a484a31bfa3d826fb44643185a76502c64 04-add-to-render-cloudcfg.patch
+15ce19f650c145cba57286ac6138dbc48fc7923e29d8ff0b9acd443b5bb74896676c1ecdca67a2a706332be3e0621ec347defbe926c3541d4f6529554204ca47 05-add-ca_certs-module-support.patch
+8f7c52c493409bb2c82be88c623e5d75c8bea3b9b37fa4da8967ec25670ea47d236dff3ac3e0373304175e1ac3e8b1a9182ae6e9ffd601ab7a9e6f4367170524 06-add-ntp-module-support.patch
+e93cd17971cd890d938a7db1af805edf944d34048ca222bfda9bb8b81626a196b51e0c2fdc048d83ff562e912d44f4670341867bcb87b760a354ca4dc2d9542a 07-add-power_state-module-support.patch
+2871a0adfa70df2101b292829dc13f2b8a894b851b27d8f2579e3aebc598b849166f4dee9e27d0fda8680421f546c371c05a3526ea54606806bc288a95939ccc 08-add-resolv_conf-module-support.patch
+659dd1a094074be1870e471469d227fe5b41334766816bc88fd0ed42153fdb4eb53248565a17021ad10565d73747d806bed8f6aa2a7681bb1d1ef096df6b9746 alpine.py
+3484432f4b577ece2c26657b5c5f48e1fd184ea7a1bef67ef111df0e76d9fe2c17031150be37cd88d3097d1a7a5d08309dfcd372788aae7e38389f5ac3ce1eec cc_apk_configure.py
+f671ce6e54b8c6a1e3a1bd47fe93d380b1d12906be88891f00ee6e1f789bdc0ed38a777664cb1b7d6618a73e1dce47ee4f30d0831334f3bd3274aed11f063de4 chrony.conf.alpine.tmpl
+9b009f83ff739bab9ceeb653fb41f6d42b562bdf0fbc67bf42bff53f903fc0da5dda1cf10375c0f94fbf086f3710620bf0302d1c9bec2d39abfd0cb737bc6e42 hosts.alpine.tmpl
+48b25ec4457c2b3772a7d210033551d041749a0d1869818d888030e6df7fd9bbc13a38b95cf465de3d46d96881a722f94a337584ce48f280c4a52b819586563a interfaces
+bcba9a8da0c9c6dcd318fc67635e56847a8b94f61cc5b494464dfda51d21dbde56de32ba5573047c63522bf19e77a1be483c2dfbaeec0844e8fc75a160ff3a5e ntp.conf.alpine.tmpl"
diff --git a/testing/cloud-init/alpine.py b/testing/cloud-init/alpine.py
index 31b9e1840b..2555a2f877 100644
--- a/testing/cloud-init/alpine.py
+++ b/testing/cloud-init/alpine.py
@@ -26,9 +26,24 @@ from cloudinit.settings import PER_INSTANCE
LOG = logging.getLogger(__name__)
+NETWORK_FILE_HEADER = """\
+# This file is generated from information provided by the datasource. Changes
+# to it will not persist across an instance reboot. To disable cloud-init's
+# network configuration capabilities, write a file
+# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
+# network: {config: disabled}
+"""
+
+
class Distro(distros.Distro):
- network_conf_fn = "/etc/network/interfaces"
+ network_conf_fn = {
+ "eni": "/etc/network/interfaces"
+ }
init_cmd = ['rc-service'] # init scripts
+ renderer_configs = {
+ "eni": {"eni_path": network_conf_fn["eni"],
+ "eni_header": NETWORK_FILE_HEADER}
+ }
def __init__(self, name, cfg, paths):
distros.Distro.__init__(self, name, cfg, paths)
@@ -47,9 +62,8 @@ class Distro(distros.Distro):
self.update_package_sources()
self.package_command('add', pkgs=pkglist)
- def _write_network(self, settings):
- util.write_file(self.network_conf_fn, settings)
- return ['all']
+ def _write_network_config(self, netconfig):
+ return self._supported_write_network_config(netconfig)
def _bring_up_interfaces(self, device_names):
use_all = False
@@ -57,7 +71,7 @@ class Distro(distros.Distro):
if d == 'all':
use_all = True
if use_all:
- return distros.Distro._bring_up_interface(self, '--all')
+ return distros.Distro._bring_up_interface(self, '-a')
else:
return distros.Distro._bring_up_interfaces(self, device_names)
@@ -130,76 +144,12 @@ class Distro(distros.Distro):
self._runner.run("update-sources", self.package_command,
["update"], freq=PER_INSTANCE)
- def add_user(self, name, **kwargs):
- if util.is_user(name):
- LOG.info("User %s already exists, skipping." % name)
- return
-
- adduser_cmd = ['adduser', name, '-D']
- log_adduser_cmd = ['adduser', name, '-D']
-
- # Since we are creating users, we want to carefully validate the
- # inputs. If something goes wrong, we can end up with a system
- # that nobody can login to.
- adduser_opts = {
- "gecos": '-g',
- "homedir": '-h',
- "uid": '-u',
- "shell": '-s',
- }
-
- adduser_flags = {
- "system": '-S',
- }
-
- redact_opts = ['passwd']
-
- # Check the values and create the command
- for key, val in kwargs.items():
-
- if key in adduser_opts and val and isinstance(val, str):
- adduser_cmd.extend([adduser_opts[key], val])
-
- # Redact certain fields from the logs
- if key in redact_opts:
- log_adduser_cmd.extend([adduser_opts[key], 'REDACTED'])
- else:
- log_adduser_cmd.extend([adduser_opts[key], val])
-
- elif key in adduser_flags and val:
- adduser_cmd.append(adduser_flags[key])
- log_adduser_cmd.append(adduser_flags[key])
-
- # Don't create the home directory if directed so or if the user is a
- # system user
- if 'no_create_home' in kwargs or 'system' in kwargs:
- adduser_cmd.append('-H')
- log_adduser_cmd.append('-H')
-
- # Run the command
- LOG.debug("Adding user %s", name)
- try:
- util.subp(adduser_cmd, logstring=log_adduser_cmd)
- except Exception as e:
- util.logexc(LOG, "Failed to create user %s", name)
- raise e
+ @property
+ def preferred_ntp_clients(self):
+ """Allow distro to determine the preferred ntp client list"""
+ if not self._preferred_ntp_clients:
+ self._preferred_ntp_clients = ['chrony']
- # Unlock the user
- LOG.debug("Unlocking user %s", name)
- try:
- util.subp(['passwd', '-u', name], logstring=['passwd', '-u', name])
- except Exception as e:
- util.logexc(LOG, "Failed to unlock user %s", name)
- raise e
-
- if 'groups' in kwargs:
- groups = kwargs['groups']
- if groups and isinstance(groups, str):
- # Why are these even a single string in the first place?
- groups = groups.split(',')
- for group in groups:
- try:
- util.subp(['adduser', name, group], logstring=['adduser', name, group])
- except Exception as e:
- util.logexc(LOG, "Failed to add user %s to group %s", name, group)
- raise e
+ return self._preferred_ntp_clients
+
+# vi: ts=4 expandtab
diff --git a/testing/cloud-init/cc_apk_configure.py b/testing/cloud-init/cc_apk_configure.py
new file mode 100644
index 0000000000..54b89b8e66
--- /dev/null
+++ b/testing/cloud-init/cc_apk_configure.py
@@ -0,0 +1,148 @@
+# Copyright (c) 2020 Dermot Bradley
+#
+# Author: Dermot Bradley <dermot_bradley@yahoo.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Alternatively, this program may be used under the terms of the Apache
+# License, Version 2.0, in which case the provisions of that license are
+# applicable instead of those above. If you wish to allow use of your
+# version of this program under the terms of the Apache License, Version 2.0
+# only, indicate your decision by deleting the provisions above and replace
+# them with the notice and other provisions required by the Apache License,
+# Version 2.0. If you do not delete the provisions above, a recipient may
+# use your version of this file under the terms of either the GPLv3 or the
+# Apache License, Version 2.0.
+
+"""
+Apk Configure
+-------------
+**Summary:** configure apk
+
+This module handles configuration of the /etc/apk/repositories file.
+
+.. note::
+ To ensure that apk configuration is valid yaml, any strings containing
+ special characters, especially ``:`` should be quoted.
+
+**Preserve repositories:**
+
+By default, cloud-init will generate a new repositories file based on any
+configuration specified in cloud config. To disable this behavior and preserve
+the existing repositories file set ``preserve_repositories`` to ``true``.
+
+.. note::
+ The ``preserve_repositories`` option overrides all other config keys that
+ would alter the repositories file.
+
+**Specify repositories entries:**
+
+The alpine_repo entry under ``apk_repos`` is a dictionary which contains the
+following keys:
+
+ - ``version``: the version of Alpine (either "vX.Y" or "edge")
+ - ``base_url``: the base URL (up to, but not including, the version) of an
+ Alpine mirror to use (optional)
+ - ``community_enabled``: whether to enable the Community repository
+ (optional, defaults to false)
+ - ``testing_enabled``: whether to enable the Testing repository (optional,
+ defaults to false)
+
+The local_repo entry under ``apk_repos`` is an optional dictionary which
+contains the following key:
+
+ - ``base_url``: the base URL (up to, but not including, the architecture
+ name) of a repository of unofficial Alpine packages
+
+**Internal name:** ``cc_apk_configure``
+
+**Module frequency:** per instance
+
+**Supported distros:** alpine
+
+**Config keys**::
+
+ apk_repos:
+ preserve_repositories: <true/false>
+ alpine_repo:
+ - version: "<alpine version>"
+ base_url: "<repo base url>"
+ community_enabled: <true/false>
+ testing_enabled: <true/false>
+ local_repo:
+ - base_url: "<repo base url>"
+"""
+
+import os
+
+from cloudinit import log as logging
+from cloudinit import util
+
+distros = ['alpine']
+
+
+def _write_repositories_file(alpine_repo, local_baseurl, log):
+ repo_file = '/etc/apk/repositories'
+
+ alpine_baseurl = alpine_repo.get('base_url')
+ if not alpine_baseurl:
+ # Default Alpine mirror to use
+ alpine_baseurl = 'https://alpine.global.ssl.fastly.net/alpine'
+
+ alpine_version = alpine_repo.get('version')
+
+ repo_config = '#\n# Created by cloud-init\n#\n'
+ repo_config += '# This file is written on first boot of an instance\n#\n'
+
+ repo_config += "\n%s/%s/main" % (alpine_baseurl, alpine_version)
+ if alpine_repo.get('community_enabled'):
+ repo_config += "\n%s/%s/community" % (alpine_baseurl, alpine_version)
+ if alpine_repo.get('testing_enabled'):
+ repo_config += "\n\n@testing %s/edge/testing" % alpine_baseurl
+
+ if local_baseurl != '':
+ repo_config += "\n\n@local %s\n" % local_baseurl
+ util.write_file(repo_file, repo_config)
+
+
+def handle(name, cfg, cloud, log, _args):
+
+ apk_section = cfg.get('apk_repos')
+ if not apk_section:
+ log.debug(("Skipping module named %s,"
+ " no 'apk_repos' section found"), name)
+ return
+
+ if util.is_true(apk_section.get('preserve_repositories'), False):
+ log.debug(("Skipping module named %s,"
+ " 'preserve_repositories' is set"), name)
+ return
+
+ alpine_repo = apk_section.get('alpine_repo')
+ if not alpine_repo:
+ log.debug(("Skipping module named %s,"
+ " no 'alpine_repo' configuration found"), name)
+ return
+
+ alpine_version = alpine_repo.get('version')
+ if not alpine_version:
+ log.debug(("Skipping module named %s,"
+ " 'version' not specified in alpine_repo"), name)
+ return
+
+ local_repo = apk_section.get('local_repo', {})
+ local_baseurl = local_repo.get('base_url')
+
+ _write_repositories_file(alpine_repo, local_baseurl, log)
+
+# vi: ts=4 expandtab
diff --git a/testing/cloud-init/chrony.conf.alpine.tmpl b/testing/cloud-init/chrony.conf.alpine.tmpl
new file mode 100644
index 0000000000..45efc18c3c
--- /dev/null
+++ b/testing/cloud-init/chrony.conf.alpine.tmpl
@@ -0,0 +1,38 @@
+## template:jinja
+# Welcome to the chrony configuration file. See chrony.conf(5) for more
+# information about usable directives.
+{% if pools %}# pools
+{% endif %}
+{% for pool in pools -%}
+pool {{pool}} iburst
+{% endfor %}
+{%- if servers %}# servers
+{% endif %}
+{% for server in servers -%}
+server {{server}} iburst
+{% endfor %}
+
+# This directive specifies the location of the file containing ID/key pairs for
+# NTP authentication.
+keyfile /etc/chrony/chrony.keys
+
+# This directive specifies the file into which chronyd will store the rate
+# information.
+driftfile /var/lib/chrony/chrony.drift
+
+# Uncomment the following line to turn logging on.
+#log tracking measurements statistics
+
+# Log files location.
+logdir /var/log/chrony
+
+# Stop bad estimates upsetting machine clock.
+maxupdateskew 100.0
+
+# This directive enables kernel synchronisation (every 11 minutes) of the
+# real-time clock. Note that it can’t be used along with the 'rtcfile' directive.
+rtcsync
+
+# Step the system clock instead of slewing it if the adjustment is larger than
+# one second, but only in the first three clock updates.
+makestep 1 3
diff --git a/testing/cloud-init/cloud.cfg b/testing/cloud-init/cloud.cfg
deleted file mode 100644
index 26f1362448..0000000000
--- a/testing/cloud-init/cloud.cfg
+++ /dev/null
@@ -1,76 +0,0 @@
-# The top level settings are used as module
-# and system configuration.
-
-# A set of users which may be applied and/or used by various modules
-# when a 'default' entry is found it will reference the 'default_user'
-# from the distro configuration specified below
-users:
- - default
-
-# If this is set, 'root' will not be able to ssh in and they
-# will get a message to login instead as the above $user (ubuntu)
-disable_root: true
-ssh_pwauth: false
-
-# This will cause the set+update hostname module to not operate (if true)
-# preserve_hostname: false
-
-syslog_fix_perms: root:root
-
-ssh_deletekeys: false
-ssh_genkeytypes: [rsa, dsa]
-
-cloud_init_modules:
- - seed_random
- - bootcmd
- - write-files
- - growpart
- - resizefs
- - set_hostname
- - update_hostname
- - update_etc_hosts
- - ca-certs
- - users-groups
- - ssh
-
-cloud_config_modules:
- - disk_setup
- - mounts
- - ssh-import-id
- - set-passwords
- - timezone
- - puppet
- - chef
- - salt-minion
- - mcollective
- - disable-ec2-metadata
- - runcmd
-
-cloud_final_modules:
- - scripts-vendor
- - scripts-per-once
- - scripts-per-boot
- - scripts-per-instance
- - scripts-user
- - ssh-authkey-fingerprints
- - keys-to-console
- - phone-home
- - final-message
- - power-state-change
-
-# System and/or distro specific settings
-# (not accessible to handlers/transforms)
-system_info:
- # This will affect which distro class gets used
- distro: alpine
- # Default user name + that default users groups (if added/used)
- default_user:
- name: alpine
- lock_passwd: false
- gecos: Alpine
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/ash
- # Other config here will be given to the distro class and/or path classes
- paths:
- cloud_dir: /var/lib/cloud/
- templates_dir: /etc/cloud/templates/
diff --git a/testing/cloud-init/hosts.alpine.tmpl b/testing/cloud-init/hosts.alpine.tmpl
index 27662289fd..8b2cfcd81e 100644
--- a/testing/cloud-init/hosts.alpine.tmpl
+++ b/testing/cloud-init/hosts.alpine.tmpl
@@ -3,21 +3,24 @@
This file /etc/cloud/templates/hosts.alpine.tmpl is only utilized
if enabled in cloud-config. Specifically, in order to enable it
you need to add the following to config:
- manage_etc_hosts: template
+ manage_etc_hosts: True
-#}
-# Your system has configured 'manage_etc_hosts' as 'template'.
+# Your system has configured 'manage_etc_hosts' as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.alpine.tmpl
# b.) change or remove the value of 'manage_etc_hosts' in
# /etc/cloud/cloud.cfg or cloud-config from user-data
-#
+#
# The following lines are desirable for IPv4 capable hosts
-127.0.0.1 {{fqdn}} {{hostname}}
-127.0.0.1 localhost.localdomain localhost
-127.0.0.1 localhost4.localdomain4 localhost4
+127.0.1.1 {{fqdn}} {{hostname}}
+127.0.0.1 localhost ip4-localhost
# The following lines are desirable for IPv6 capable hosts
::1 {{fqdn}} {{hostname}}
-::1 localhost.localdomain localhost
-::1 localhost6.localdomain6 localhost6
+::1 ip6-localhost ip6-loopback
+fe00::0 ip6-localnet
+ff00::0 ip6-mcastprefix
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
+ff02::3 ip6-allhosts
diff --git a/testing/cloud-init/interfaces b/testing/cloud-init/interfaces
new file mode 100644
index 0000000000..fbf5feb1cc
--- /dev/null
+++ b/testing/cloud-init/interfaces
@@ -0,0 +1,11 @@
+#
+# /etc/network/interfaces
+#
+# Sample stub interfaces file - there needs to be one already present (which
+# will then be replaced) whenever cloud-init runs as otherwise it will fail
+# to perform the network setup.
+#
+
+# The loopback network interface
+auto lo
+iface lo inet loopback
diff --git a/testing/cloud-init/ntp.conf.alpine.tmpl b/testing/cloud-init/ntp.conf.alpine.tmpl
new file mode 100644
index 0000000000..2ab9614cf2
--- /dev/null
+++ b/testing/cloud-init/ntp.conf.alpine.tmpl
@@ -0,0 +1,10 @@
+## template:jinja
+
+# /etc/ntp.conf, configuration for Busybox ntpd - it only supports
+# "server" lines.
+
+{%- if servers %}# Servers
+{% endif %}
+{% for server in servers -%}
+server {{server}}
+{% endfor %}