Mail archive
alpine-aports

[alpine-aports] [PATCH 6/6] testing/cloud-init: new aport

From: Matt Dainty <matt+alpine_at_bodgit-n-scarper.com>
Date: Thu, 24 Mar 2016 16:33:23 +0000

http://launchpad.net/cloud-init
Cloud instance init scripts
---
 testing/cloud-init/10-setup.patch          |  12 ++
 testing/cloud-init/20-alpine.patch         | 219 +++++++++++++++++++++++++++++
 testing/cloud-init/APKBUILD                |  84 +++++++++++
 testing/cloud-init/cloud-config.initd      |  13 ++
 testing/cloud-init/cloud-final.initd       |  11 ++
 testing/cloud-init/cloud-init-local.initd  |  13 ++
 testing/cloud-init/cloud-init.initd        |  14 ++
 testing/cloud-init/cloud-init.post-install |   4 +
 testing/cloud-init/cloud-init.pre-install  |   4 +
 testing/cloud-init/cloud.cfg               |  74 ++++++++++
 testing/cloud-init/hosts.alpine.tmpl       |  23 +++
 11 files changed, 471 insertions(+)
 create mode 100644 testing/cloud-init/10-setup.patch
 create mode 100644 testing/cloud-init/20-alpine.patch
 create mode 100644 testing/cloud-init/APKBUILD
 create mode 100644 testing/cloud-init/cloud-config.initd
 create mode 100644 testing/cloud-init/cloud-final.initd
 create mode 100644 testing/cloud-init/cloud-init-local.initd
 create mode 100644 testing/cloud-init/cloud-init.initd
 create mode 100644 testing/cloud-init/cloud-init.post-install
 create mode 100644 testing/cloud-init/cloud-init.pre-install
 create mode 100644 testing/cloud-init/cloud.cfg
 create mode 100644 testing/cloud-init/hosts.alpine.tmpl
diff --git a/testing/cloud-init/10-setup.patch b/testing/cloud-init/10-setup.patch
new file mode 100644
index 0000000..6ee9a7c
--- /dev/null
+++ b/testing/cloud-init/10-setup.patch
_at_@ -0,0 +1,12 @@
+--- cloud-init-0.7.6/setup.py.orig
++++ cloud-init-0.7.6/setup.py
+_at_@ -160,9 +160,4 @@
+                    [f for f in glob('doc/examples/seed/*') if is_f(f)]),
+                  ],
+       install_requires=read_requires(),
+-      cmdclass={
+-          # Use a subclass for install that handles
+-          # adding on the right init system configuration files
+-          'install': InitsysInstallData,
+-      },
+       )
diff --git a/testing/cloud-init/20-alpine.patch b/testing/cloud-init/20-alpine.patch
new file mode 100644
index 0000000..e2db6a3
--- /dev/null
+++ b/testing/cloud-init/20-alpine.patch
_at_@ -0,0 +1,219 @@
+=== modified file 'cloudinit/distros/__init__.py'
+--- a/cloudinit/distros/__init__.py	2014-09-10 18:32:37 +0000
++++ b/cloudinit/distros/__init__.py	2016-03-01 10:16:18 +0000
+_at_@ -43,6 +43,7 @@
+     'freebsd': ['freebsd'],
+     'suse': ['sles'],
+     'arch': ['arch'],
++    'alpine': ['alpine'],
+ }
+ 
+ LOG = logging.getLogger(__name__)
+
+=== added file 'cloudinit/distros/alpine.py'
+--- a/cloudinit/distros/alpine.py	1970-01-01 00:00:00 +0000
++++ b/cloudinit/distros/alpine.py	2016-03-01 10:21:41 +0000
+_at_@ -0,0 +1,203 @@
++# vi: ts=4 expandtab
++#
++#    Copyright (C) 2016 Matt Dainty
++#
++#    Author: Matt Dainty <matt_at_bodgit-n-scarper.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/>.
++
++from cloudinit import distros
++from cloudinit import helpers
++from cloudinit import log as logging
++from cloudinit import util
++
++from cloudinit.distros.parsers.hostname import HostnameConf
++
++from cloudinit.settings import PER_INSTANCE
++
++LOG = logging.getLogger(__name__)
++
++
++class Distro(distros.Distro):
++    network_conf_fn = "/etc/network/interfaces"
++    init_cmd = ['rc-service']  # init scripts
++
++    def __init__(self, name, cfg, paths):
++        distros.Distro.__init__(self, name, cfg, paths)
++        # This will be used to restrict certain
++        # calls from repeatly happening (when they
++        # should only happen say once per instance...)
++        self._runner = helpers.Runners(paths)
++        self.osfamily = 'alpine'
++        cfg['ssh_svcname'] = 'sshd'
++
++    def apply_locale(self, locale, out_fn=None):
++        # No locale support yet
++        pass
++
++    def install_packages(self, pkglist):
++        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 _bring_up_interfaces(self, device_names):
++        use_all = False
++        for d in device_names:
++            if d == 'all':
++                use_all = True
++        if use_all:
++            return distros.Distro._bring_up_interface(self, '--all')
++        else:
++            return distros.Distro._bring_up_interfaces(self, device_names)
++
++    def _select_hostname(self, hostname, fqdn):
++        # Prefer the short hostname over the long
++        # fully qualified domain name
++        if not hostname:
++            return fqdn
++        return hostname
++
++    def _write_hostname(self, your_hostname, out_fn):
++        conf = None
++        try:
++            # Try to update the previous one
++            # so lets see if we can read it first.
++            conf = self._read_hostname_conf(out_fn)
++        except IOError:
++            pass
++        if not conf:
++            conf = HostnameConf('')
++        conf.set_hostname(your_hostname)
++        util.write_file(out_fn, str(conf), 0644)
++
++    def _read_system_hostname(self):
++        sys_hostname = self._read_hostname(self.hostname_conf_fn)
++        return (self.hostname_conf_fn, sys_hostname)
++
++    def _read_hostname_conf(self, filename):
++        conf = HostnameConf(util.load_file(filename))
++        conf.parse()
++        return conf
++
++    def _read_hostname(self, filename, default=None):
++        hostname = None
++        try:
++            conf = self._read_hostname_conf(filename)
++            hostname = conf.hostname
++        except IOError:
++            pass
++        if not hostname:
++            return default
++        return hostname
++
++    def set_timezone(self, tz):
++        distros.set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
++
++    def package_command(self, command, args=None, pkgs=None):
++        if pkgs is None:
++            pkgs = []
++
++        cmd = ['apk']
++        # Redirect output
++        cmd.append("--quiet")
++
++        if args and isinstance(args, str):
++            cmd.append(args)
++        elif args and isinstance(args, list):
++            cmd.extend(args)
++
++        if command:
++            cmd.append(command)
++
++        pkglist = util.expand_package_list('%s-%s', pkgs)
++        cmd.extend(pkglist)
++
++        # Allow the output of this to flow outwards (ie not be captured)
++        util.subp(cmd, capture=False)
++
++    def update_package_sources(self):
++        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
++
++        if 'groups' in kwargs:
++            groups = kwargs['groups']
++            if isinstance(groups, six.string_types):
++                # Why are these even a single string in the first place?
++                groups = [groups.split(',')]
++            for group in kwargs['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
++
++    def lock_passwd(self, name):
++        # Already locked
++        pass
diff --git a/testing/cloud-init/APKBUILD b/testing/cloud-init/APKBUILD
new file mode 100644
index 0000000..0316abd
--- /dev/null
+++ b/testing/cloud-init/APKBUILD
_at_@ -0,0 +1,84 @@
+# Contributor: Matt Dainty <matt+alpine_at_bodgit-n-scarper.com>
+# Maintainer:
+pkgname=cloud-init
+pkgver=0.7.6
+pkgrel=0
+pkgdesc="Cloud instance init scripts"
+url="http://launchpad.net/cloud-init"
+arch="noarch"
+license="GPL"
+depends="python py-cheetah py-configobj py-jinja2 py-jsonpatch py-oauth2 py-prettytable py-requests py-serial py-yaml"
+makedepends="py-setuptools"
+install="$pkgname.pre-install $pkgname.post-install"
+subpackages="$pkgname-doc"
+source="
+	https://launchpad.net/$pkgname/trunk/$pkgver/+download/$pkgname-$pkgver.tar.gz
+	10-setup.patch
+	20-alpine.patch
+	cloud-init-local.initd
+	cloud-init.initd
+	cloud-config.initd
+	cloud-final.initd
+	cloud.cfg
+	hosts.alpine.tmpl
+	"
+
+_builddir="$srcdir"/$pkgname-$pkgver
+prepare() {
+	local i
+	cd "$_builddir"
+	for i in $source; do
+		case $i in
+		*.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
+		esac
+	done
+}
+
+build() {
+	cd "$_builddir"
+	python setup.py build || return 1
+}
+
+package() {
+	cd "$_builddir"
+	python setup.py install --prefix=/usr --root="$pkgdir" || return 1
+
+	for i in init-local init config final; do
+		install -m755 -D "$srcdir"/cloud-$i.initd \
+			"$pkgdir"/etc/init.d/cloud-$i || return 1
+	done
+
+	install -m644 "$srcdir"/cloud.cfg \
+		"$pkgdir"/etc/cloud/
+
+	install -m644 "$srcdir"/hosts.alpine.tmpl \
+		"$pkgdir"/etc/cloud/templates/
+}
+
+md5sums="cd392e943dd0165e90a6d56afd0e4ad3  cloud-init-0.7.6.tar.gz
+90a78c24b1a2ed537d5e7c28c48780d5  10-setup.patch
+00c660d93a85bbe9c891e01141467619  20-alpine.patch
+80892c13e65a5040f32b4d86e848b6bb  cloud-init-local.initd
+0041569a737713ea01a154d98007c2e5  cloud-init.initd
+3ff3ae1e27950abf3064da60c23669ba  cloud-config.initd
+0824fad27c2bf1b966e8820f51d2fde0  cloud-final.initd
+7956e83fe1c2fb306990efe02a0bc201  cloud.cfg
+3e700738d75419687128a93cbdc35857  hosts.alpine.tmpl"
+sha256sums="9e8fd22eb7f6e40ae6a5f66173ddc3cc18f65ee406c460a728092b37db2f3ed7  cloud-init-0.7.6.tar.gz
+a26154be7b331859660c620ad56f59910b1a832fff3a1d0597a1d8204e1b7846  10-setup.patch
+1c516faedb0a6fa3ef075ac4a0ca9858062ef8ec8f4c8d5edd3257e5b872b86b  20-alpine.patch
+0fc8f79a4675e57b9475ac8fbe92898b17284f6ad903ec1ea9a795783e70ed33  cloud-init-local.initd
+ce227ff37516fc08702996903762704dd255a16d391ed2853fe5d5b88d28231d  cloud-init.initd
+3581bf4d4a0b7011edef76c40237517c3fb350c477ffaead1abcdcf4bb8bbe24  cloud-config.initd
+1e5fe801a9981a721e4cb6ebc1f7fd9df2dec1683dae9ab6fd15f8e8338fb7d3  cloud-final.initd
+4a522aeca8aad6b986057110afa0519eb47e27f23342ef06b1485b6f0676dc2e  cloud.cfg
+43bcfcd5ff1117a9b54be22f5e50f04aa78fe6574271be7c01d472921d3f04c3  hosts.alpine.tmpl"
+sha512sums="aa2397328afda8e77ed6d642e7642f41a4b4b5bcd3d0e87056aa8c88b56624ec65c57cfc66b0d13ccc235f1840baf1d577316974902a0439cf2f2eb0f8eef36d  cloud-init-0.7.6.tar.gz
+502de73eb899d751f025d7d268d3a4eb086177a86da5d6e223b7243ecdb30b93bd3ecb974cfa1f900d2adc8ce2bbc8cd1be23a10115e709b1f2cc22b704d575d  10-setup.patch
+d42e9abb9dbfa3d61ce4b3aaad3633ae75a2bc097775a5c350b4ca0060da2ea99fe66fd602ed60a3e4c0d56eb9d6509bc1fc543babae749a96dad7175b4832d2  20-alpine.patch
+f3131d9fb8b59fb44be1bb9293cfc1809c370efd4c4d215f5a3b337305bf4982d98d4905bcf077b32edfb4d0b605a4db5704779ac667c3546a9cbdd54a95e28e  cloud-init-local.initd
+dccdbbe2e8ff7cdf28da2f6ddbbcda3f3c29c99d8b89476d03cb2e46e158614f7a5deea2284d807938e9d12600f642747cd020bd88412d6f3906195d78aa9f5e  cloud-init.initd
+644b583eb96ec93bfe71fea27408f29ef432b7535d70dc3eb4b2a99b5131c30310971e4502d100047f0909ce00f58ef42fd9be907a99388dc9f7b98ba3f27ebf  cloud-config.initd
+22970d575b5576689b638badfc1248b4710edb33421470b42d0d838a99806b01cefd9346033dc22a062c9eb6c52625966d73722386da9ad632f65fdcd2f10d93  cloud-final.initd
+4ac8b60e9e6af7de8694d7c6658d1f1aec0f91334090796a2190714f5025207fccd2a84a6b4d780fa8928af8f2daf16f5bef5ffd9ba57f7b7e3c0e3b694453a0  cloud.cfg
+813a67d446ee65f5ef5a45fe60bef4d0e404c5d1f9cb732bc0ec0b706a0274f4bc1e7f87e676da1ca9366c2f933163f620ee296ed783372869438dd8a928117b  hosts.alpine.tmpl"
diff --git a/testing/cloud-init/cloud-config.initd b/testing/cloud-init/cloud-config.initd
new file mode 100644
index 0000000..b0fa786
--- /dev/null
+++ b/testing/cloud-init/cloud-config.initd
_at_@ -0,0 +1,13 @@
+#!/sbin/runscript
+
+depend() {
+  after cloud-init-local
+  after cloud-init
+  before cloud-final
+  provide cloud-config
+}
+
+start() {
+  cloud-init modules --mode config
+  eend 0
+}
diff --git a/testing/cloud-init/cloud-final.initd b/testing/cloud-init/cloud-final.initd
new file mode 100644
index 0000000..b457a35
--- /dev/null
+++ b/testing/cloud-init/cloud-final.initd
_at_@ -0,0 +1,11 @@
+#!/sbin/runscript
+
+depend() {
+  after cloud-config
+  provide cloud-final
+}
+
+start() {
+  cloud-init modules --mode final
+  eend 0
+}
diff --git a/testing/cloud-init/cloud-init-local.initd b/testing/cloud-init/cloud-init-local.initd
new file mode 100644
index 0000000..9d47263
--- /dev/null
+++ b/testing/cloud-init/cloud-init-local.initd
_at_@ -0,0 +1,13 @@
+#!/sbin/runscript
+
+depend() {
+  after localmount
+  after netmount
+  before cloud-init
+  provide cloud-init-local
+}
+
+start() {
+  cloud-init init --local
+  eend 0
+}
diff --git a/testing/cloud-init/cloud-init.initd b/testing/cloud-init/cloud-init.initd
new file mode 100644
index 0000000..c901449
--- /dev/null
+++ b/testing/cloud-init/cloud-init.initd
_at_@ -0,0 +1,14 @@
+#!/sbin/runscript
+
+depend() {
+  need net
+  after firewall
+  after cloud-init-local
+  before cloud-config
+  provide cloud-init
+}
+
+start() {
+  cloud-init init
+  eend 0
+}
diff --git a/testing/cloud-init/cloud-init.post-install b/testing/cloud-init/cloud-init.post-install
new file mode 100644
index 0000000..0586fcd
--- /dev/null
+++ b/testing/cloud-init/cloud-init.post-install
_at_@ -0,0 +1,4 @@
+#!/bin/sh
+
+# add something which happends after install
+
diff --git a/testing/cloud-init/cloud-init.pre-install b/testing/cloud-init/cloud-init.pre-install
new file mode 100644
index 0000000..46079e0
--- /dev/null
+++ b/testing/cloud-init/cloud-init.pre-install
_at_@ -0,0 +1,4 @@
+#!/bin/sh
+
+# add something which happends before install
+
diff --git a/testing/cloud-init/cloud.cfg b/testing/cloud-init/cloud.cfg
new file mode 100644
index 0000000..c300588
--- /dev/null
+++ b/testing/cloud-init/cloud.cfg
_at_@ -0,0 +1,74 @@
+# 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
+
+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
+     gecos: Alpine
+     sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+     shell: /bin/bash
+   # 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
new file mode 100644
index 0000000..2766228
--- /dev/null
+++ b/testing/cloud-init/hosts.alpine.tmpl
_at_@ -0,0 +1,23 @@
+## template:jinja
+{#
+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
+-#}
+# Your system has configured 'manage_etc_hosts' as 'template'.
+# 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
+
+# The following lines are desirable for IPv6 capable hosts
+::1 {{fqdn}} {{hostname}}
+::1 localhost.localdomain localhost
+::1 localhost6.localdomain6 localhost6
-- 
2.6.4
---
Unsubscribe:  alpine-aports+unsubscribe_at_lists.alpinelinux.org
Help:         alpine-aports+help_at_lists.alpinelinux.org
---
Received on Thu Mar 24 2016 - 16:33:23 GMT