X-Original-To: alpine-aports@mail.alpinelinux.org Delivered-To: alpine-aports@mail.alpinelinux.org Received: from mail.alpinelinux.org (dallas-a1.alpinelinux.org [127.0.0.1]) by mail.alpinelinux.org (Postfix) with ESMTP id A4965DD260C for ; Thu, 24 Mar 2016 16:33:54 +0000 (UTC) Received: from mail.bodgit-n-scarper.com (simulant.bodgit-n-scarper.com [97.107.139.112]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.alpinelinux.org (Postfix) with ESMTPS id 597FEDD0223 for ; Thu, 24 Mar 2016 16:33:54 +0000 (UTC) Received: from 72f38b3a9c55.cisco.com (unknown [173.38.220.38]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (Client did not present a certificate) (Authenticated sender: matt) by mail.bodgit-n-scarper.com (Postfix) with ESMTP id 9AEBE859A; Thu, 24 Mar 2016 12:33:53 -0400 (EDT) From: Matt Dainty To: alpine-aports@lists.alpinelinux.org Cc: Matt Dainty Subject: [alpine-aports] [PATCH 6/6] testing/cloud-init: new aport Date: Thu, 24 Mar 2016 16:33:23 +0000 Message-Id: <1458837203-8163-7-git-send-email-matt+alpine@bodgit-n-scarper.com> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1458837203-8163-1-git-send-email-matt+alpine@bodgit-n-scarper.com> References: <1458837203-8163-1-git-send-email-matt+alpine@bodgit-n-scarper.com> X-Virus-Scanned: ClamAV using ClamSMTP X-Mailinglist: alpine-aports Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: 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 @@ -0,0 +1,12 @@ +--- cloud-init-0.7.6/setup.py.orig ++++ cloud-init-0.7.6/setup.py +@@ -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 @@ -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 +@@ -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 +@@ -0,0 +1,203 @@ ++# vi: ts=4 expandtab ++# ++# Copyright (C) 2016 Matt Dainty ++# ++# Author: Matt Dainty ++# ++# 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 . ++ ++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 @@ -0,0 +1,84 @@ +# Contributor: Matt Dainty +# 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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@lists.alpinelinux.org Help: alpine-aports+help@lists.alpinelinux.org ---