- update to version 0.7.4

+ fix issue mounting 'ephemeral0' if ephemeral0 was an alias for a
    partitioned block device with target filesystem on ephemeral0.1.
    (LP: #1236594)
  + fix DataSourceAzure incompatibility with 2.6 (LP: #1232175)
  + fix power_state_change config module so that example works.  Improve
    its documentation and add reference to 'timeout'
  + support apt-add-archive with 'cloud-archive:' format.  (LP: #1244355)
  + Change SmartOS verb for availability zone (LP: #1249124)
  + documentation fix for boothooks to use 'cloud-init-per'
  + fix resizefs module by supporting kernels that do not have
    /proc/PID/mountinfo.  (LP: #1248625) [Tim Daly Jr.]
  + fix 'make rpm' by removing 0.6.4 entry from ChangeLog (LP: #1241834)
  + fix omnibus chef installer (LP: #1182265) [Chris Wing]
  + small fix for OVF datasource for iso transport on non-iso9660 filesystem
  + determine if upstart version is suitable for
    'initctl reload-configuration' (LP: #1124384).  If so, then invoke it.
    supports setting up instance-store disk with partition table and filesystem.
  + add Azure datasource.
  + add support for SuSE / SLES [Juerg Haefliger]
  + add a trailing carriage return to chpasswd input, which reportedly
    caused a problem on rhel5 if missing.
  + support individual MIME segments to be gzip compressed (LP: #1203203)
  + always finalize handlers even if processing failed (LP: #1203368)
  + support merging into cloud-config via jsonp. (LP: #1200476)
  + add datasource 'SmartOS' for Joyent Cloud.  Adds a dependency on serial.
  + add 'log_time' helper to util for timing how long things take
    which also reads from uptime. uptime is useful as clock may change during
    boot due to ntp.
  + prefer growpart resizer to 'parted resizepart' (LP: #1212492)

OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=4
This commit is contained in:
Robert Schweikert 2014-01-04 17:43:26 +00:00 committed by Git OBS Bridge
parent ddcfa56afe
commit c6ec6841cd
10 changed files with 638 additions and 659 deletions

24
addopenSUSEBase.diff Normal file
View File

@ -0,0 +1,24 @@
diff -urN cloud-init-0.7.4.orig/cloudinit/config/cc_resolv_conf.py cloud-init-0.7.4/cloudinit/config/cc_resolv_conf.py
--- cloud-init-0.7.4.orig/cloudinit/config/cc_resolv_conf.py 2014-01-04 10:11:25.900655759 -0500
+++ cloud-init-0.7.4/cloudinit/config/cc_resolv_conf.py 2014-01-04 10:51:27.900181158 -0500
@@ -55,7 +55,7 @@
frequency = PER_INSTANCE
-distros = ['fedora', 'rhel', 'sles']
+distros = ['fedora', 'opensuse', 'rhel', 'sles']
def generate_resolv_conf(cloud, log, params):
diff -urN cloud-init-0.7.4.orig/cloudinit/distros/__init__.py cloud-init-0.7.4/cloudinit/distros/__init__.py
--- cloud-init-0.7.4.orig/cloudinit/distros/__init__.py 2014-01-04 10:11:25.919655399 -0500
+++ cloud-init-0.7.4/cloudinit/distros/__init__.py 2014-01-04 10:53:09.936206936 -0500
@@ -39,7 +39,7 @@
OSFAMILIES = {
'debian': ['debian', 'ubuntu'],
'redhat': ['fedora', 'rhel'],
- 'suse': ['sles']
+ 'suse': ['opensuse', 'sles']
}
LOG = logging.getLogger(__name__)

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cc5ab984596100f76e95c7a02dabb2ac7ce27cd2e46a590f793fca2afe121ab0
size 377139

3
cloud-init-0.7.4.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3029756b58963e0acd7d878750ee3a1971a7037cad8f31532b62ac1a1315872a
size 416437

View File

@ -1,3 +1,57 @@
-------------------------------------------------------------------
Sat Jan 4 16:03:57 UTC 2014 - rschweikert@suse.com
- update to version 0.7.4
+ fix issue mounting 'ephemeral0' if ephemeral0 was an alias for a
partitioned block device with target filesystem on ephemeral0.1.
(LP: #1236594)
+ fix DataSourceAzure incompatibility with 2.6 (LP: #1232175)
+ fix power_state_change config module so that example works. Improve
its documentation and add reference to 'timeout'
+ support apt-add-archive with 'cloud-archive:' format. (LP: #1244355)
+ Change SmartOS verb for availability zone (LP: #1249124)
+ documentation fix for boothooks to use 'cloud-init-per'
+ fix resizefs module by supporting kernels that do not have
/proc/PID/mountinfo. (LP: #1248625) [Tim Daly Jr.]
+ fix 'make rpm' by removing 0.6.4 entry from ChangeLog (LP: #1241834)
+ fix omnibus chef installer (LP: #1182265) [Chris Wing]
+ small fix for OVF datasource for iso transport on non-iso9660 filesystem
+ determine if upstart version is suitable for
'initctl reload-configuration' (LP: #1124384). If so, then invoke it.
supports setting up instance-store disk with partition table and filesystem.
+ add Azure datasource.
+ add support for SuSE / SLES [Juerg Haefliger]
+ add a trailing carriage return to chpasswd input, which reportedly
caused a problem on rhel5 if missing.
+ support individual MIME segments to be gzip compressed (LP: #1203203)
+ always finalize handlers even if processing failed (LP: #1203368)
+ support merging into cloud-config via jsonp. (LP: #1200476)
+ add datasource 'SmartOS' for Joyent Cloud. Adds a dependency on serial.
+ add 'log_time' helper to util for timing how long things take
which also reads from uptime. uptime is useful as clock may change during
boot due to ntp.
+ prefer growpart resizer to 'parted resizepart' (LP: #1212492)
+ support random data seed from config drive or azure, and a module
'seed_random' to read that and write it to /dev/urandom.
+ add OpenNebula Datasource [Vlastimil Holer]
+ add 'cc_disk_setup' config module for paritioning disks and creating
filesystems. Useful if attached disks are not formatted (LP: #1218506)
+ Fix usage of libselinux-python when selinux is disabled. [Garrett Holmstrom]
+ multi_log: only write to /dev/console if it exists [Garrett Holmstrom]
+ config/cloud.cfg: add 'sudo' to list groups for the default user
(LP: #1228228)
+ documentation fix for use of 'mkpasswd' [Eric Nordlund]
+ respect /etc/growroot-disabled file (LP: #1234331)
- replace fixupSysVinit.patch with suseSysVInit.diff
+ sysV init files are now maintained by distribution, thus we need a patch
that has the complete sysV init files rather then modifying existing files
- remove slesHandler.patch
+ SLES support is now integrated upstream
- add addopenSUSEBase.diff
+ remnants of the slesHandler.patch that add information about openSUSE
- add setupSUSEsysVInit.diff
+ integrate the SUSE sysV init scripts into setup.py
------------------------------------------------------------------- -------------------------------------------------------------------
Fri Aug 2 06:57:30 UTC 2013 - rschweikert@suse.com Fri Aug 2 06:57:30 UTC 2013 - rschweikert@suse.com

View File

@ -16,7 +16,7 @@
# #
Name: cloud-init Name: cloud-init
Version: 0.7.2 Version: 0.7.4
Release: 0 Release: 0
License: GPL-3.0 License: GPL-3.0
Summary: Cloud node initialization tool Summary: Cloud node initialization tool
@ -24,9 +24,10 @@ Url: http://launchpad.net/cloud-init/
Group: System/Management Group: System/Management
Source0: %{name}-%{version}.tar.bz2 Source0: %{name}-%{version}.tar.bz2
Source1: cloud.cfg.suse Source1: cloud.cfg.suse
Patch0: fixupSysVinit.patch Patch0: suseSysVInit.diff
Patch1: slesHandler.patch Patch1: addopenSUSEBase.diff
Patch2: openSUSEHandler.diff Patch2: openSUSEHandler.diff
Patch3: setupSUSEsysVInit.diff
BuildRequires: fdupes BuildRequires: fdupes
BuildRequires: filesystem BuildRequires: filesystem
BuildRequires: python-devel BuildRequires: python-devel
@ -47,7 +48,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch BuildArch: noarch
%endif %endif
%if 0%{?suse_version} && 0%{?suse_version} <= 1210 %if 0%{?suse_version} && 0%{?suse_version} <= 1210
%define initsys sysvinit %define initsys sysvinit_suse
%else %else
%define initsys systemd %define initsys systemd
BuildRequires: systemd BuildRequires: systemd
@ -87,17 +88,16 @@ Unit tests for the cloud-init tools
%prep %prep
%setup -q %setup -q
%patch0 %patch0 -p1
%patch1 -p1 %patch1 -p1
%patch2 -p1 %patch2 -p1
%patch3 -p1
%if 0%{?suse_version} <= 1130 %if 0%{?suse_version} <= 1130
# disable ecdsa for SLE 11 (not available) # disable ecdsa for SLE 11 (not available)
echo "ssh_genkeytypes: ['rsa', 'dsa']" >> %{SOURCE1} echo "ssh_genkeytypes: ['rsa', 'dsa']" >> %{SOURCE1}
%endif %endif
# Install service files into correct location # Install service files into correct location
sed -i "s|/etc/systemd/system|%{systemd_prefix}/systemd/system|" setup.py sed -i "s|/etc/systemd/system|%{systemd_prefix}/systemd/system|" setup.py
# Drop $all facility Required-Start in sysvinit/cloud-final:
sed -i "s|\$all cloud-config|cloud-config|" sysvinit/cloud-final
%build %build
python setup.py build python setup.py build
@ -123,12 +123,6 @@ sed -i s/INSERT_SUSE_DISTRO/sles/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
sed -i s/INSERT_SUSE_DISTRO/opensuse/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg sed -i s/INSERT_SUSE_DISTRO/opensuse/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
%endif %endif
%endif %endif
#grep Enterprise /etc/SuSE-release >& /dev/null
#if [ $? = 0 ]; then
#sed -i s/INSERT_SUSE_DISTRO/sles/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
#else
#sed -i s/INSERT_SUSE_DISTRO/opensuse/ %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg
#fi
# remove debian/ubuntu specific profile.d file (bnc#779553) # remove debian/ubuntu specific profile.d file (bnc#779553)
rm -f %{buildroot}%{_sysconfdir}/profile.d/Z99-cloud-locale-test.sh rm -f %{buildroot}%{_sysconfdir}/profile.d/Z99-cloud-locale-test.sh
@ -136,7 +130,6 @@ rm -f %{buildroot}%{_sysconfdir}/profile.d/Z99-cloud-locale-test.sh
# move sysvinit scripts into the "right" place # move sysvinit scripts into the "right" place
%if 0%{?suse_version} && 0%{?suse_version} <= 1210 %if 0%{?suse_version} && 0%{?suse_version} <= 1210
mkdir -p %{buildroot}/%{_initddir} mkdir -p %{buildroot}/%{_initddir}
mv %{buildroot}%{_sysconfdir}/rc.d/init.d/* %{buildroot}%{_initddir}/
mkdir -p %{buildroot}/%{_sbindir} mkdir -p %{buildroot}/%{_sbindir}
pushd "%{buildroot}%{_initddir}" pushd "%{buildroot}%{_initddir}"
for iniF in *; do for iniF in *; do

View File

@ -1,157 +0,0 @@
Index: sysvinit/cloud-config
===================================================================
--- sysvinit/cloud-config.orig
+++ sysvinit/cloud-config
@@ -27,9 +27,9 @@
# Provides: cloud-config
# Required-Start: cloud-init cloud-init-local
# Should-Start: $time
-# Required-Stop:
-# Should-Stop:
-# Default-Start: 2 3 4 5
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: The config cloud-init job
# Description: Start cloud-init and runs the config phase
@@ -62,6 +62,9 @@ conf="/etc/cloud/cloud.cfg"
[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+. /etc/rc.status
+rc_reset
+
start() {
[ -x $cloud_init ] || return 5
[ -f $conf ] || return 6
@@ -118,4 +121,6 @@ case "$1" in
;;
esac
-exit $RETVAL
+_rc_status=$RETVAL
+rc_status -v
+rc_exit
Index: sysvinit/cloud-final
===================================================================
--- sysvinit/cloud-final.orig
+++ sysvinit/cloud-final
@@ -27,9 +27,9 @@
# Provides: cloud-final
# Required-Start: $all cloud-config
# Should-Start: $time
-# Required-Stop:
-# Should-Stop:
-# Default-Start: 2 3 4 5
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: The final cloud-init job
# Description: Start cloud-init and runs the final phase
@@ -62,6 +62,9 @@ conf="/etc/cloud/cloud.cfg"
[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+. /etc/rc.status
+rc_reset
+
start() {
[ -x $cloud_init ] || return 5
[ -f $conf ] || return 6
@@ -118,4 +121,6 @@ case "$1" in
;;
esac
-exit $RETVAL
+_rc_status=$RETVAL
+rc_status -v
+rc_exit
Index: sysvinit/cloud-init
===================================================================
--- sysvinit/cloud-init.orig
+++ sysvinit/cloud-init
@@ -27,9 +27,9 @@
# Provides: cloud-init
# Required-Start: $local_fs $network $named $remote_fs cloud-init-local
# Should-Start: $time
-# Required-Stop:
-# Should-Stop:
-# Default-Start: 2 3 4 5
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: The initial cloud-init job (net and fs contingent)
# Description: Start cloud-init and runs the initialization phase
@@ -62,6 +62,9 @@ conf="/etc/cloud/cloud.cfg"
[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+. /etc/rc.status
+rc_reset
+
start() {
[ -x $cloud_init ] || return 5
[ -f $conf ] || return 6
@@ -103,6 +106,8 @@ case "$1" in
;;
status)
echo -n $"Checking for service $prog:"
+ RETVAL=3
+ [ -e /root/.ssh/authorized_keys ] && RETVAL=0
# Return value is slightly different for the status command:
# 0 - service up and running
# 1 - service dead, but /var/run/ pid file exists
@@ -110,7 +115,6 @@ case "$1" in
# 3 - service not running (unused)
# 4 - service status unknown :-(
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
- RETVAL=3
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|condrestart|restart|force-reload|reload}"
@@ -118,4 +122,6 @@ case "$1" in
;;
esac
-exit $RETVAL
+_rc_status=$RETVAL
+rc_status -v
+rc_exit
Index: sysvinit/cloud-init-local
===================================================================
--- sysvinit/cloud-init-local.orig
+++ sysvinit/cloud-init-local
@@ -27,9 +27,9 @@
# Provides: cloud-init-local
# Required-Start: $local_fs $remote_fs
# Should-Start: $time
-# Required-Stop:
-# Should-Stop:
-# Default-Start: 2 3 4 5
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: The initial cloud-init job (local fs contingent)
# Description: Start cloud-init and runs the initialization phases
@@ -62,6 +62,9 @@ conf="/etc/cloud/cloud.cfg"
[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+. /etc/rc.status
+rc_reset
+
start() {
[ -x $cloud_init ] || return 5
[ -f $conf ] || return 6
@@ -118,4 +121,6 @@ case "$1" in
;;
esac
-exit $RETVAL
+_rc_status=$RETVAL
+rc_status -v
+rc_exit

View File

@ -1,6 +1,6 @@
diff -urN cloud-init-0.7.2/cloudinit/distros/opensuse.py cloud-init-0.7.2.os/cloudinit/distros/opensuse.py diff -urN cloud-init-0.7.4/cloudinit/distros/opensuse.py cloud-init-0.7.4.os/cloudinit/distros/opensuse.py
--- cloud-init-0.7.2/cloudinit/distros/opensuse.py 1969-12-31 19:00:00.000000000 -0500 --- cloud-init-0.7.4/cloudinit/distros/opensuse.py 1969-12-31 19:00:00.000000000 -0500
+++ cloud-init-0.7.2.os/cloudinit/distros/opensuse.py 2013-06-15 06:26:15.312348359 -0400 +++ cloud-init-0.7.4.os/cloudinit/distros/opensuse.py 2013-06-15 06:26:15.312348359 -0400
@@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
+# vi: ts=4 expandtab +# vi: ts=4 expandtab
+# +#

18
setupSUSEsysVInit.diff Normal file
View File

@ -0,0 +1,18 @@
diff -uNr cloud-init-0.7.4.orig/setup.py cloud-init-0.7.4/setup.py
--- cloud-init-0.7.4.orig/setup.py 2014-01-04 12:26:55.704357892 -0500
+++ cloud-init-0.7.4/setup.py 2014-01-04 12:31:24.023166380 -0500
@@ -39,12 +39,14 @@
INITSYS_FILES = {
'sysvinit': [f for f in glob('sysvinit/redhat/*') if is_f(f)],
'sysvinit_deb': [f for f in glob('sysvinit/debian/*') if is_f(f)],
+ 'sysvinit_suse': [f for f in glob('sysvinit/suse/*') if is_f(f)],
'systemd': [f for f in glob('systemd/*') if is_f(f)],
'upstart': [f for f in glob('upstart/*') if is_f(f)],
}
INITSYS_ROOTS = {
'sysvinit': '/etc/rc.d/init.d',
'sysvinit_deb': '/etc/init.d',
+ 'sysvinit_suse': '/etc/init.d',
'systemd': '/etc/systemd/system/',
'upstart': '/etc/init/',
}

View File

@ -1,482 +0,0 @@
Index: cloud-init-0.7.2/cloudinit/config/cc_resolv_conf.py
===================================================================
--- cloud-init-0.7.2.orig/cloudinit/config/cc_resolv_conf.py 2013-06-18 15:11:17.016476944 +0200
+++ cloud-init-0.7.2/cloudinit/config/cc_resolv_conf.py 2013-06-18 15:11:55.760669066 +0200
@@ -1,8 +1,12 @@
# vi: ts=4 expandtab
#
# Copyright (C) 2013 Craig Tracey
+# Copyright (C) 2013 SUSE LLC
+# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Craig Tracey <craigtracey@gmail.com>
+# Author: Robert Schweikert <rjschwei@suse.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.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
@@ -53,7 +57,7 @@
frequency = PER_INSTANCE
-distros = ['fedora', 'rhel']
+distros = ['fedora', 'opensuse', 'rhel', 'sles']
def generate_resolv_conf(cloud, log, params):
Index: cloud-init-0.7.2/cloudinit/distros/__init__.py
===================================================================
--- cloud-init-0.7.2.orig/cloudinit/distros/__init__.py 2013-06-18 15:11:16.996476840 +0200
+++ cloud-init-0.7.2/cloudinit/distros/__init__.py 2013-06-18 15:12:18.848783546 +0200
@@ -1,13 +1,15 @@
# vi: ts=4 expandtab
#
# Copyright (C) 2012 Canonical Ltd.
-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012, 2013 Hewlett-Packard Development Company, L.P.
# Copyright (C) 2012 Yahoo! Inc.
+# Copyright (C) 2013 SUSE LLC
#
# Author: Scott Moser <scott.moser@canonical.com>
# Author: Juerg Haefliger <juerg.haefliger@hp.com>
# Author: Joshua Harlow <harlowja@yahoo-inc.com>
# Author: Ben Howard <ben.howard@canonical.com>
+# Author: Robert Schweikert <rjschwei@suse.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
@@ -38,7 +40,8 @@
OSFAMILIES = {
'debian': ['debian', 'ubuntu'],
- 'redhat': ['fedora', 'rhel']
+ 'redhat': ['fedora', 'rhel'],
+ 'suse': ['opensuse', 'sles']
}
LOG = logging.getLogger(__name__)
@@ -347,7 +350,8 @@
try:
util.subp(adduser_cmd, logstring=x_adduser_cmd)
except Exception as e:
- util.logexc(LOG, "Failed to create user %s due to error.", e)
+ util.logexc(LOG, "Failed to create user %s due to error.",
+ name)
raise e
# Set password if plain-text password provided
@@ -358,10 +362,10 @@
# lock account unless lock_password is False.
if kwargs.get('lock_passwd', True):
try:
- util.subp(['passwd', '--lock', name])
+ util.subp(['passwd', '-l', name])
except Exception as e:
- util.logexc(LOG, ("Failed to disable password logins for"
- "user %s" % name), e)
+ util.logexc(LOG, "Failed to disable password logins for "
+ "user %s", name)
raise e
# Configure sudo access
@@ -385,7 +389,7 @@
try:
util.subp(cmd, pass_string, logstring="chpasswd for %s" % user)
except Exception as e:
- util.logexc(LOG, "Failed to set password for %s" % user)
+ util.logexc(LOG, "Failed to set password for %s", user)
raise e
return True
@@ -427,7 +431,7 @@
util.append_file(sudo_base, sudoers_contents)
LOG.debug("Added '#includedir %s' to %s" % (path, sudo_base))
except IOError as e:
- util.logexc(LOG, "Failed to write %s" % sudo_base, e)
+ util.logexc(LOG, "Failed to write %s", sudo_base)
raise e
util.ensure_dir(path, 0750)
@@ -479,7 +483,7 @@
util.subp(group_add_cmd)
LOG.info("Created new group %s" % name)
except Exception as e:
- util.logexc("Failed to create group %s" % name, e)
+ util.logexc("Failed to create group %s", name)
# Add members to the group, if so defined
if len(members) > 0:
Index: cloud-init-0.7.2/cloudinit/distros/sles.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ cloud-init-0.7.2/cloudinit/distros/sles.py 2013-06-18 15:11:55.764669081 +0200
@@ -0,0 +1,340 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2013 SUSE LLC
+# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
+#
+# Author: Robert Schweikert <rjschwei@suse.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+#
+# Leaning very heavily on the RHEL and Debian implementation
+#
+# 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/>.
+
+import os
+
+from cloudinit import distros
+
+from cloudinit.distros.parsers.hostname import HostnameConf
+from cloudinit.distros.parsers.resolv_conf import ResolvConf
+from cloudinit.distros.parsers.sys_conf import SysConf
+
+from cloudinit import helpers
+from cloudinit import log as logging
+from cloudinit import util
+
+from cloudinit.settings import PER_INSTANCE
+
+LOG = logging.getLogger(__name__)
+
+
+class Distro(distros.Distro):
+ clock_conf_fn = '/etc/sysconfig/clock'
+ locale_conf_fn = '/etc/sysconfig/language'
+ network_conf_fn = '/etc/sysconfig/network'
+ hostname_conf_fn = '/etc/HOSTNAME'
+ network_script_tpl = '/etc/sysconfig/network/ifcfg-%s'
+ resolve_conf_fn = '/etc/resolv.conf'
+ tz_local_fn = '/etc/localtime'
+ tz_zone_dir = '/usr/share/zoneinfo'
+
+ 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 = 'suse'
+
+ def install_packages(self, pkglist):
+ self.package_command('install', args='-l', pkgs=pkglist)
+
+ def _adjust_resolve(self, dns_servers, search_servers):
+ try:
+ r_conf = ResolvConf(util.load_file(self.resolve_conf_fn))
+ r_conf.parse()
+ except IOError:
+ util.logexc(LOG,
+ "Failed at parsing %s reverting to an empty instance",
+ self.resolve_conf_fn)
+ r_conf = ResolvConf('')
+ r_conf.parse()
+ if dns_servers:
+ for s in dns_servers:
+ try:
+ r_conf.add_nameserver(s)
+ except ValueError:
+ util.logexc(LOG, "Failed at adding nameserver %s", s)
+ if search_servers:
+ for s in search_servers:
+ try:
+ r_conf.add_search_domain(s)
+ except ValueError:
+ util.logexc(LOG, "Failed at adding search domain %s", s)
+ util.write_file(self.resolve_conf_fn, str(r_conf), 0644)
+
+ def _write_network(self, settings):
+ # Convert debian settings to ifcfg format
+ entries = translate_network(settings)
+ LOG.debug("Translated ubuntu style network settings %s into %s",
+ settings, entries)
+ # Make the intermediate format as the suse format...
+ nameservers = []
+ searchservers = []
+ dev_names = entries.keys()
+ for (dev, info) in entries.iteritems():
+ net_fn = self.network_script_tpl % (dev)
+ mode = info.get('auto')
+ if mode and mode.lower() == 'true':
+ mode = 'auto'
+ else:
+ mode = 'manual'
+ net_cfg = {
+ 'BOOTPROTO': info.get('bootproto'),
+ 'BROADCAST': info.get('broadcast'),
+ 'GATEWAY': info.get('gateway'),
+ 'IPADDR': info.get('address'),
+ 'LLADDR': info.get('hwaddress'),
+ 'NETMASK': info.get('netmask'),
+ 'STARTMODE': mode,
+ 'USERCONTROL': 'no'
+ }
+ if dev != 'lo':
+ net_cfg['ETHERDEVICE'] = dev
+ net_cfg['ETHTOOL_OPTIONS'] = ''
+ else:
+ net_cfg['FIREWALL'] = 'no'
+ self._update_sysconfig_file(net_fn, net_cfg, True)
+ if 'dns-nameservers' in info:
+ nameservers.extend(info['dns-nameservers'])
+ if 'dns-search' in info:
+ searchservers.extend(info['dns-search'])
+ if nameservers or searchservers:
+ self._adjust_resolve(nameservers, searchservers)
+ return dev_names
+
+ def _update_sysconfig_file(self, fn, adjustments, allow_empty=False):
+ if not adjustments:
+ return
+ (exists, contents) = self._read_conf(fn)
+ updated_am = 0
+ for (k, v) in adjustments.items():
+ if v is None:
+ continue
+ v = str(v)
+ if len(v) == 0 and not allow_empty:
+ continue
+ contents[k] = v
+ updated_am += 1
+ if updated_am:
+ lines = [
+ str(contents),
+ ]
+ if not exists:
+ lines.insert(0, util.make_header())
+ util.write_file(fn, "\n".join(lines) + "\n", 0644)
+
+ def _read_conf(self, fn):
+ exists = False
+ try:
+ contents = util.load_file(fn).splitlines()
+ exists = True
+ except IOError:
+ contents = []
+ return (exists,
+ SysConf(contents))
+
+ def apply_locale(self, locale, out_fn=None):
+ if not out_fn:
+ out_fn = self.locale_conf_fn
+ locale_cfg = {
+ 'RC_LANG': locale,
+ }
+ self._update_sysconfig_file(out_fn, locale_cfg)
+
+ 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, 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(hostname)
+ util.write_file(out_fn, str(conf), 0644)
+
+ def _read_system_hostname(self):
+ host_fn = self.hostname_conf_fn
+ return (host_fn, self._read_hostname(host_fn))
+
+ 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 _bring_up_interfaces(self, device_names):
+ if device_names and 'all' in device_names:
+ raise RuntimeError(('Distro %s can not translate '
+ 'the device name "all"') % (self.name))
+ return distros.Distro._bring_up_interfaces(self, device_names)
+
+ def set_timezone(self, tz):
+ # TODO(harlowja): move this code into
+ # the parent distro...
+ tz_file = os.path.join(self.tz_zone_dir, str(tz))
+ if not os.path.isfile(tz_file):
+ raise RuntimeError(("Invalid timezone %s,"
+ " no file found at %s") % (tz, tz_file))
+ # Adjust the sysconfig clock zone setting
+ clock_cfg = {
+ 'TIMEZONE': str(tz),
+ }
+ self._update_sysconfig_file(self.clock_conf_fn, clock_cfg)
+ # This ensures that the correct tz will be used for the system
+ util.copy(tz_file, self.tz_local_fn)
+
+ def package_command(self, command, args=None, pkgs=None):
+ if pkgs is None:
+ pkgs = []
+
+ cmd = ['zypper']
+ # No user interaction possible, enable non-interactive mode
+ cmd.append('--non-interactive')
+ # Do not check the keys, we assume that the initial repos configured
+ # in the image can be trusted
+ cmd.append('--no-gpg-checks')
+
+ # Comand is the operation, such as install
+ cmd.append(command)
+
+ # args are the arguments to the command, not global options
+ if args and isinstance(args, str):
+ cmd.append(args)
+ elif args and isinstance(args, list):
+ cmd.extend(args)
+
+ 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,
+ ['refresh'], freq=PER_INSTANCE)
+
+
+def translate_network(settings):
+ # Translate Debian based distro interface blobs as given in
+ # /etc/network/interfaces to an equivalent format for distributions
+ # that use ifcfg-* style (RedHat and SUSE). (copied from rhel.py)
+ # Get the standard cmd, args from the ubuntu format
+ entries = []
+ for line in settings.splitlines():
+ line = line.strip()
+ if not line or line.startswith("#"):
+ continue
+ split_up = line.split(None, 1)
+ if len(split_up) <= 1:
+ continue
+ entries.append(split_up)
+ # Figure out where each iface section is
+ ifaces = []
+ consume = {}
+ for (cmd, args) in entries:
+ if cmd == 'iface':
+ if consume:
+ ifaces.append(consume)
+ consume = {}
+ consume[cmd] = args
+ else:
+ consume[cmd] = args
+ # Check if anything left over to consume
+ absorb = False
+ for (cmd, args) in consume.iteritems():
+ if cmd == 'iface':
+ absorb = True
+ if absorb:
+ ifaces.append(consume)
+ # Now translate
+ real_ifaces = {}
+ for info in ifaces:
+ if 'iface' not in info:
+ continue
+ iface_details = info['iface'].split(None)
+ dev_name = None
+ if len(iface_details) >= 1:
+ dev = iface_details[0].strip().lower()
+ if dev:
+ dev_name = dev
+ if not dev_name:
+ continue
+ iface_info = {}
+ if len(iface_details) >= 3:
+ proto_type = iface_details[2].strip().lower()
+ # Seems like this can be 'loopback' which we don't
+ # really care about
+ if proto_type in ['dhcp', 'static']:
+ iface_info['bootproto'] = proto_type
+ # These can just be copied over
+ for k in ['netmask', 'address', 'gateway', 'broadcast']:
+ if k in info:
+ val = info[k].strip().lower()
+ if val:
+ iface_info[k] = val
+ # Name server info provided??
+ if 'dns-nameservers' in info:
+ iface_info['dns-nameservers'] = info['dns-nameservers'].split()
+ # Name server search info provided??
+ if 'dns-search' in info:
+ iface_info['dns-search'] = info['dns-search'].split()
+ # Is any mac address spoofing going on??
+ if 'hwaddress' in info:
+ hw_info = info['hwaddress'].lower().strip()
+ hw_split = hw_info.split(None, 1)
+ if len(hw_split) == 2 and hw_split[0].startswith('ether'):
+ hw_addr = hw_split[1]
+ if hw_addr:
+ iface_info['hwaddress'] = hw_addr
+ real_ifaces[dev_name] = iface_info
+ # Check for those that should be started on boot via 'auto'
+ for (cmd, args) in entries:
+ if cmd == 'auto':
+ # Seems like auto can be like 'auto eth0 eth0:1' so just get the
+ # first part out as the device name
+ args = args.split(None)
+ if not args:
+ continue
+ dev_name = args[0].strip().lower()
+ if dev_name in real_ifaces:
+ real_ifaces[dev_name]['auto'] = True
+ return real_ifaces
Index: cloud-init-0.7.2/templates/hosts.suse.tmpl
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ cloud-init-0.7.2/templates/hosts.suse.tmpl 2013-06-18 15:11:55.764669081 +0200
@@ -0,0 +1,24 @@
+#*
+ This file /etc/cloud/templates/hosts.suse.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: True
+*#
+# 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.suse.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 localhost
+
+# The following lines are desirable for IPv6 capable hosts
+::1 localhost ipv6-localhost ipv6-loopback
+fe00::0 ipv6-localnet
+
+ff00::0 ipv6-mcastprefix
+ff02::1 ipv6-allnodes
+ff02::2 ipv6-allrouters
+ff02::3 ipv6-allhosts

529
suseSysVInit.diff Normal file
View File

@ -0,0 +1,529 @@
diff -urN cloud-init-0.7.4.orig/sysvinit/suse/cloud-config cloud-init-0.7.4/sysvinit/suse/cloud-config
--- cloud-init-0.7.4.orig/sysvinit/suse/cloud-config 1969-12-31 19:00:00.000000000 -0500
+++ cloud-init-0.7.4/sysvinit/suse/cloud-config 2014-01-04 10:41:15.261034684 -0500
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+#
+# Copyright (C) 2012 Yahoo! Inc.
+# Copyright (C) 2013 SUSE LLC
+#
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+# Author: Robert Schweikert <rjschwei@suse.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/>.
+#
+
+# See: http://wiki.debian.org/LSBInitScripts
+# See: http://tiny.cc/czvbgw
+# See: http://www.novell.com/coolsolutions/feature/15380.html
+# Also based on dhcpd in RHEL (for comparison)
+
+### BEGIN INIT INFO
+# Provides: cloud-config
+# Required-Start: cloud-init cloud-init-local
+# Should-Start: $time
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
+# Default-Stop: 0 1 6
+# Short-Description: The config cloud-init job
+# Description: Start cloud-init and runs the config phase
+# and any associated config modules as desired.
+### END INIT INFO
+
+# Return values acc. to LSB for all commands but status:
+# 0 - success
+# 1 - generic or unspecified error
+# 2 - invalid or excess argument(s)
+# 3 - unimplemented feature (e.g. "reload")
+# 4 - user had insufficient privileges
+# 5 - program is not installed
+# 6 - program is not configured
+# 7 - program is not running
+# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
+#
+# Note that starting an already running service, stopping
+# or restarting a not-running service as well as the restart
+# with force-reload (in case signaling is not supported) are
+# considered a success.
+
+RETVAL=0
+
+prog="cloud-init"
+cloud_init="/usr/bin/cloud-init"
+conf="/etc/cloud/cloud.cfg"
+
+# If there exist sysconfig/default variable override files use it...
+[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
+[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+
+. /etc/rc.status
+rc_reset
+
+start() {
+ [ -x $cloud_init ] || return 5
+ [ -f $conf ] || return 6
+
+ echo -n $"Starting $prog: "
+ $cloud_init $CLOUDINITARGS modules --mode config
+ RETVAL=$?
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Shutting down $prog: "
+ # No-op
+ RETVAL=7
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ RETVAL=$?
+ ;;
+ stop)
+ stop
+ RETVAL=$?
+ ;;
+ restart|try-restart|condrestart)
+ ## Stop the service and regardless of whether it was
+ ## running or not, start it again.
+ #
+ ## Note: try-restart is now part of LSB (as of 1.9).
+ ## RH has a similar command named condrestart.
+ start
+ RETVAL=$?
+ ;;
+ reload|force-reload)
+ # It does not support reload
+ RETVAL=3
+ ;;
+ status)
+ echo -n $"Checking for service $prog:"
+ # Return value is slightly different for the status command:
+ # 0 - service up and running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running (unused)
+ # 4 - service status unknown :-(
+ # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
+ RETVAL=3
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|try-restart|condrestart|restart|force-reload|reload}"
+ RETVAL=3
+ ;;
+esac
+
+_rc_status=$RETVAL
+rc_status -v
+rc_exit
diff -urN cloud-init-0.7.4.orig/sysvinit/suse/cloud-final cloud-init-0.7.4/sysvinit/suse/cloud-final
--- cloud-init-0.7.4.orig/sysvinit/suse/cloud-final 1969-12-31 19:00:00.000000000 -0500
+++ cloud-init-0.7.4/sysvinit/suse/cloud-final 2014-01-04 10:40:57.354381148 -0500
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+#
+# Copyright (C) 2012 Yahoo! Inc.
+# Copyright (C) 2013 SUSE LLC
+#
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+# Author: Robert Schweikert <rjschwei@suse.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/>.
+#
+
+# See: http://wiki.debian.org/LSBInitScripts
+# See: http://tiny.cc/czvbgw
+# See: http://www.novell.com/coolsolutions/feature/15380.html
+# Also based on dhcpd in RHEL (for comparison)
+
+### BEGIN INIT INFO
+# Provides: cloud-final
+# Required-Start: cloud-config
+# Should-Start: $time
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
+# Default-Stop: 0 1 6
+# Short-Description: The final cloud-init job
+# Description: Start cloud-init and runs the final phase
+# and any associated final modules as desired.
+### END INIT INFO
+
+# Return values acc. to LSB for all commands but status:
+# 0 - success
+# 1 - generic or unspecified error
+# 2 - invalid or excess argument(s)
+# 3 - unimplemented feature (e.g. "reload")
+# 4 - user had insufficient privileges
+# 5 - program is not installed
+# 6 - program is not configured
+# 7 - program is not running
+# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
+#
+# Note that starting an already running service, stopping
+# or restarting a not-running service as well as the restart
+# with force-reload (in case signaling is not supported) are
+# considered a success.
+
+RETVAL=0
+
+prog="cloud-init"
+cloud_init="/usr/bin/cloud-init"
+conf="/etc/cloud/cloud.cfg"
+
+# If there exist sysconfig/default variable override files use it...
+[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
+[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+
+. /etc/rc.status
+rc_reset
+
+start() {
+ [ -x $cloud_init ] || return 5
+ [ -f $conf ] || return 6
+
+ echo -n $"Starting $prog: "
+ $cloud_init $CLOUDINITARGS modules --mode final
+ RETVAL=$?
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Shutting down $prog: "
+ # No-op
+ RETVAL=7
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ RETVAL=$?
+ ;;
+ stop)
+ stop
+ RETVAL=$?
+ ;;
+ restart|try-restart|condrestart)
+ ## Stop the service and regardless of whether it was
+ ## running or not, start it again.
+ #
+ ## Note: try-restart is now part of LSB (as of 1.9).
+ ## RH has a similar command named condrestart.
+ start
+ RETVAL=$?
+ ;;
+ reload|force-reload)
+ # It does not support reload
+ RETVAL=3
+ ;;
+ status)
+ echo -n $"Checking for service $prog:"
+ # Return value is slightly different for the status command:
+ # 0 - service up and running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running (unused)
+ # 4 - service status unknown :-(
+ # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
+ RETVAL=3
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|try-restart|condrestart|restart|force-reload|reload}"
+ RETVAL=3
+ ;;
+esac
+
+_rc_status=$RETVAL
+rc_status -v
+rc_exit
diff -urN cloud-init-0.7.4.orig/sysvinit/suse/cloud-init cloud-init-0.7.4/sysvinit/suse/cloud-init
--- cloud-init-0.7.4.orig/sysvinit/suse/cloud-init 1969-12-31 19:00:00.000000000 -0500
+++ cloud-init-0.7.4/sysvinit/suse/cloud-init 2014-01-04 10:40:41.874680652 -0500
@@ -0,0 +1,129 @@
+#!/bin/sh
+
+#
+# Copyright (C) 2012 Yahoo! Inc.
+# Copyright (C) 2013 SUSE LLC
+#
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+# Author: Robert Schweikert <rjschwei@suse.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/>.
+#
+
+# See: http://wiki.debian.org/LSBInitScripts
+# See: http://tiny.cc/czvbgw
+# See: http://www.novell.com/coolsolutions/feature/15380.html
+# Also based on dhcpd in RHEL (for comparison)
+
+### BEGIN INIT INFO
+# Provides: cloud-init
+# Required-Start: $local_fs $network $named $remote_fs cloud-init-local
+# Should-Start: $time
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
+# Default-Stop: 0 1 6
+# Short-Description: The initial cloud-init job (net and fs contingent)
+# Description: Start cloud-init and runs the initialization phase
+# and any associated initial modules as desired.
+### END INIT INFO
+
+# Return values acc. to LSB for all commands but status:
+# 0 - success
+# 1 - generic or unspecified error
+# 2 - invalid or excess argument(s)
+# 3 - unimplemented feature (e.g. "reload")
+# 4 - user had insufficient privileges
+# 5 - program is not installed
+# 6 - program is not configured
+# 7 - program is not running
+# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
+#
+# Note that starting an already running service, stopping
+# or restarting a not-running service as well as the restart
+# with force-reload (in case signaling is not supported) are
+# considered a success.
+
+RETVAL=0
+
+prog="cloud-init"
+cloud_init="/usr/bin/cloud-init"
+conf="/etc/cloud/cloud.cfg"
+
+# If there exist sysconfig/default variable override files use it...
+[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
+[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+
+. /etc/rc.status
+rc_reset
+
+start() {
+ [ -x $cloud_init ] || return 5
+ [ -f $conf ] || return 6
+
+ echo -n $"Starting $prog: "
+ $cloud_init $CLOUDINITARGS init
+ RETVAL=$?
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Shutting down $prog: "
+ # No-op
+ RETVAL=7
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ RETVAL=$?
+ ;;
+ stop)
+ stop
+ RETVAL=$?
+ ;;
+ restart|try-restart|condrestart)
+ ## Stop the service and regardless of whether it was
+ ## running or not, start it again.
+ #
+ ## Note: try-restart is now part of LSB (as of 1.9).
+ ## RH has a similar command named condrestart.
+ start
+ RETVAL=$?
+ ;;
+ reload|force-reload)
+ # It does not support reload
+ RETVAL=3
+ ;;
+ status)
+ echo -n $"Checking for service $prog:"
+ RETVAL=3
+ [ -e /root/.ssh/authorized_keys ] && RETVAL=0
+ # Return value is slightly different for the status command:
+ # 0 - service up and running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running (unused)
+ # 4 - service status unknown :-(
+ # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|try-restart|condrestart|restart|force-reload|reload}"
+ RETVAL=3
+ ;;
+esac
+
+_rc_status=$RETVAL
+rc_status -v
+rc_exit
diff -urN cloud-init-0.7.4.orig/sysvinit/suse/cloud-init-local cloud-init-0.7.4/sysvinit/suse/cloud-init-local
--- cloud-init-0.7.4.orig/sysvinit/suse/cloud-init-local 1969-12-31 19:00:00.000000000 -0500
+++ cloud-init-0.7.4/sysvinit/suse/cloud-init-local 2014-01-04 10:39:53.411618325 -0500
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+#
+# Copyright (C) 2012 Yahoo! Inc.
+# Copyright (C) 2013 SUSE LLC
+#
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+# Author: Robert Schweikert <rjschwei@suse.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/>.
+#
+
+# See: http://wiki.debian.org/LSBInitScripts
+# See: http://tiny.cc/czvbgw
+# See: http://www.novell.com/coolsolutions/feature/15380.html
+# Also based on dhcpd in RHEL (for comparison)
+
+### BEGIN INIT INFO
+# Provides: cloud-init-local
+# Required-Start: $local_fs $remote_fs
+# Should-Start: $time
+# Required-Stop: $null
+# Should-Stop: $null
+# Default-Start: 2 3 5
+# Default-Stop: 0 1 6
+# Short-Description: The initial cloud-init job (local fs contingent)
+# Description: Start cloud-init and runs the initialization phases
+# and any associated initial modules as desired.
+### END INIT INFO
+
+# Return values acc. to LSB for all commands but status:
+# 0 - success
+# 1 - generic or unspecified error
+# 2 - invalid or excess argument(s)
+# 3 - unimplemented feature (e.g. "reload")
+# 4 - user had insufficient privileges
+# 5 - program is not installed
+# 6 - program is not configured
+# 7 - program is not running
+# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
+#
+# Note that starting an already running service, stopping
+# or restarting a not-running service as well as the restart
+# with force-reload (in case signaling is not supported) are
+# considered a success.
+
+RETVAL=0
+
+prog="cloud-init"
+cloud_init="/usr/bin/cloud-init"
+conf="/etc/cloud/cloud.cfg"
+
+# If there exist sysconfig/default variable override files use it...
+[ -f /etc/sysconfig/cloud-init ] && . /etc/sysconfig/cloud-init
+[ -f /etc/default/cloud-init ] && . /etc/default/cloud-init
+
+. /etc/rc.status
+rc_reset
+
+start() {
+ [ -x $cloud_init ] || return 5
+ [ -f $conf ] || return 6
+
+ echo -n $"Starting $prog: "
+ $cloud_init $CLOUDINITARGS init --local
+ RETVAL=$?
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Shutting down $prog: "
+ # No-op
+ RETVAL=7
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ RETVAL=$?
+ ;;
+ stop)
+ stop
+ RETVAL=$?
+ ;;
+ restart|try-restart|condrestart)
+ ## Stop the service and regardless of whether it was
+ ## running or not, start it again.
+ #
+ ## Note: try-restart is now part of LSB (as of 1.9).
+ ## RH has a similar command named condrestart.
+ start
+ RETVAL=$?
+ ;;
+ reload|force-reload)
+ # It does not support reload
+ RETVAL=3
+ ;;
+ status)
+ echo -n $"Checking for service $prog:"
+ # Return value is slightly different for the status command:
+ # 0 - service up and running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running (unused)
+ # 4 - service status unknown :-(
+ # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
+ RETVAL=3
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|try-restart|condrestart|restart|force-reload|reload}"
+ RETVAL=3
+ ;;
+esac
+
+_rc_status=$RETVAL
+rc_status -v
+rc_exit