From ec265a98e0d1609bc908538ffb83ee52886fd32e Mon Sep 17 00:00:00 2001
From: Yap Sok Ann <sokann@gmail.com>
Date: Mon, 17 Jun 2013 11:29:48 +0800
Subject: [PATCH 1/5] Add OpenRC support to the service module.

---
 system/service | 69 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 61 insertions(+), 8 deletions(-)

diff --git a/system/service b/system/service
index fe3f334bfe3..8542dcbdcb1 100644
--- a/system/service
+++ b/system/service
@@ -54,6 +54,12 @@ options:
         - Whether the service should start on boot. At least one of state and
           enabled are required.
 
+    runlevel:
+        required: false
+        description:
+        - The runlevel that this service belongs to. Needed by OpenRC system
+          (e.g. Gentoo), and default to "default" if not set.
+
     arguments:
         description:
         - Additional arguments provided on the command line
@@ -77,6 +83,7 @@ examples:
 
 import platform
 import os
+import re
 import tempfile
 import shlex
 import select
@@ -107,8 +114,10 @@ class Service(object):
         self.state          = module.params['state']
         self.pattern        = module.params['pattern']
         self.enable         = module.params['enabled']
+        self.runlevel       = module.params['runlevel']
         self.changed        = False
         self.running        = None
+        self.crashed        = None
         self.action         = None
         self.svc_cmd        = None
         self.svc_initscript = None
@@ -352,7 +361,7 @@ class LinuxService(Service):
     def get_service_tools(self):
 
         paths = [ '/sbin', '/usr/sbin', '/bin', '/usr/bin' ]
-        binaries = [ 'service', 'chkconfig', 'update-rc.d', 'initctl', 'systemctl', 'start', 'stop', 'restart' ]
+        binaries = [ 'service', 'chkconfig', 'update-rc.d', 'rc-service', 'rc-update', 'initctl', 'systemctl', 'start', 'stop', 'restart' ]
         initpaths = [ '/etc/init.d' ]
         location = dict()
 
@@ -371,6 +380,11 @@ class LinuxService(Service):
         elif location.get('update-rc.d', None) and os.path.exists("/etc/init.d/%s" % self.name):
             # service is managed by with SysV init scripts, but with update-rc.d
             self.enable_cmd = location['update-rc.d']
+        elif location.get('rc-service', None) and not location.get('systemctl', None):
+            # service is managed by OpenRC
+            self.svc_cmd = location['rc-service']
+            self.enable_cmd = location['rc-update']
+            return
         elif location.get('systemctl', None):
 
             # verify service is managed by systemd
@@ -427,6 +441,11 @@ class LinuxService(Service):
             elif initctl_status_stdout.find("start/running") != -1:
                 self.running = True
 
+        if self.svc_cmd.endswith("rc-service") and self.running is None:
+            openrc_rc, openrc_status_stdout, openrc_status_stderr = self.execute_command("%s %s status" % (self.svc_cmd, self.name))
+            self.running = "started" in openrc_status_stdout
+            self.crashed = "crashed" in openrc_status_stderr
+
         # if the job status is still not known check it by response code
         # For reference, see:
         # http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
@@ -501,19 +520,44 @@ class LinuxService(Service):
             elif not self.enable:
                 return
 
-        # we change argument depending on real binary used
-        # update-rc.d wants enable/disable while
-        # chkconfig wants on/off
-        # also, systemctl needs the argument order reversed
+        if self.enable_cmd.endswith("rc-update"):
+            (rc, out, err) = self.execute_command("%s show" % self.enable_cmd)
+            for line in out.splitlines():
+                service_name, runlevels = line.split('|')
+                service_name = service_name.strip()
+                if service_name != self.name:
+                    continue
+                runlevels = re.split(r'\s+', runlevels)
+                # service already enabled for the runlevel
+                if self.enable and self.runlevel in runlevels:
+                    return
+                # service already disabled for the runlevel
+                elif not self.enable and self.runlevel not in runlevels:
+                    return
+                break
+            else:
+                # service already disabled altogether
+                if not self.enable:
+                    return
+
+        # we change argument depending on real binary used:
+        # - update-rc.d and systemctl wants enable/disable
+        # - chkconfig wants on/off
+        # - rc-update wants add/delete
+        # also, rc-update and systemctl needs the argument order reversed
         if self.enable:
             on_off = "on"
             enable_disable = "enable"
+            add_delete = "add"
         else:
             on_off = "off"
             enable_disable = "disable"
+            add_delete = "delete"
 
         if self.enable_cmd.endswith("update-rc.d"):
             args = (self.enable_cmd, self.name, enable_disable)
+        elif self.enable_cmd.endswith("rc-update"):
+            args = (self.enable_cmd, add_delete, self.name + " " + self.runlevel)
         elif self.enable_cmd.endswith("systemctl"):
             args = (self.enable_cmd, enable_disable, self.name + ".service")
         else:
@@ -534,7 +578,7 @@ class LinuxService(Service):
         arguments = self.arguments
         if self.svc_cmd:
             if not self.svc_cmd.endswith("systemctl"):
-                # SysV take the form <cmd> <name> <action>
+                # SysV and OpenRC take the form <cmd> <name> <action>
                 svc_cmd = "%s %s" % (self.svc_cmd, self.name)
             else:
                 # systemd commands take the form <cmd> <action> <name>
@@ -544,15 +588,23 @@ class LinuxService(Service):
             # upstart
             svc_cmd = "%s" % self.svc_initscript
 
+        # In OpenRC, if a service crashed, we need to reset its status to
+        # stopped with the zap command, before we can start it back.
+        if self.svc_cmd.endswith('rc-service') and self.action == 'start' and self.crashed:
+            self.execute_command("%s zap" % svc_cmd, daemonize=True)
+
         if self.action is not "restart":
             if svc_cmd != '':
-                # upstart or systemd
+                # upstart or systemd or OpenRC
                 rc_state, stdout, stderr = self.execute_command("%s %s %s" % (svc_cmd, self.action, arguments), daemonize=True)
             else:
                 # SysV
                 rc_state, stdout, stderr = self.execute_command("%s %s %s" % (self.action, self.name, arguments), daemonize=True)
+        elif self.svc_cmd.endswith('rc-service'):
+            # All services in OpenRC support restart.
+            rc_state, stdout, stderr = self.execute_command("%s %s %s" % (svc_cmd, self.action, arguments), daemonize=True)
         else:
-            # not all services support restart. Do it the hard way.
+            # In other systems, not all services support restart. Do it the hard way.
             if svc_cmd != '':
                 # upstart or systemd
                 rc1, stdout1, stderr1 = self.execute_command("%s %s %s" % (svc_cmd, 'stop', arguments), daemonize=True)
@@ -930,6 +982,7 @@ def main():
             state = dict(choices=['running', 'started', 'stopped', 'restarted', 'reloaded']),
             pattern = dict(required=False, default=None),
             enabled = dict(choices=BOOLEANS, type='bool'),
+            runlevel = dict(required=False, default='default'),
             arguments = dict(aliases=['args'], default=''),
         ),
         supports_check_mode=True

From 2ef0d94ab491778c26738f5c9e22db0527785ed6 Mon Sep 17 00:00:00 2001
From: lwade <lestertron@gmail.com>
Date: Mon, 17 Jun 2013 14:35:53 +0100
Subject: [PATCH 2/5] Added placement_group parameter for cluster compute.

---
 cloud/ec2 | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/cloud/ec2 b/cloud/ec2
index 90dcd833b39..fbcb2d018d7 100644
--- a/cloud/ec2
+++ b/cloud/ec2
@@ -142,6 +142,13 @@ options:
     required: false
     default: null
     aliases: []
+  placement_group:
+    version_added: "1.3"
+    description:
+      - placement group for the instance when using EC2 Clustered Compute
+    required: false
+    default: null
+    aliases: []
   vpc_subnet_id:
     version_added: "1.1"
     description:
@@ -223,6 +230,7 @@ def main():
             ec2_url = dict(aliases=['EC2_URL']),
             ec2_secret_key = dict(aliases=['EC2_SECRET_KEY'], no_log=True),
             ec2_access_key = dict(aliases=['EC2_ACCESS_KEY']),
+            placement_group = dict(),
             user_data = dict(),
             instance_tags = dict(),
             vpc_subnet_id = dict(),
@@ -247,6 +255,7 @@ def main():
     ec2_url = module.params.get('ec2_url')
     ec2_secret_key = module.params.get('ec2_secret_key')
     ec2_access_key = module.params.get('ec2_access_key')
+    placement_group = module.params.get('placement_group')
     user_data = module.params.get('user_data')
     instance_tags = module.params.get('instance_tags')
     vpc_subnet_id = module.params.get('vpc_subnet_id')
@@ -310,7 +319,6 @@ def main():
         count_remaining = count_remaining - len(running_instances) 
     
     # Both min_count and max_count equal count parameter. This means the launch request is explicit (we want count, or fail) in how many instances we want.
-
     
     if count_remaining > 0:
         try:
@@ -320,7 +328,8 @@ def main():
                       'min_count': count_remaining, 
                       'max_count': count_remaining,
                       'monitoring_enabled': monitoring,
-                      'placement': zone, 
+                      'placement': zone,
+                      'placement_group': placement_group, 
                       'instance_type': instance_type,
                       'kernel_id': kernel,
                       'ramdisk_id': ramdisk,

From 132ca0b3679908654409d3338f3e1b763fe81167 Mon Sep 17 00:00:00 2001
From: Joshua Lund <josh@joshlund.com>
Date: Tue, 18 Jun 2013 12:26:40 -0600
Subject: [PATCH 3/5] Fixed a few small typos

---
 cloud/quantum_router_interface | 2 +-
 notification/mail              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/cloud/quantum_router_interface b/cloud/quantum_router_interface
index dfc01e2928e..f85ac1a311b 100644
--- a/cloud/quantum_router_interface
+++ b/cloud/quantum_router_interface
@@ -239,7 +239,7 @@ def main():
     if module.params['state'] == 'absent':
         port_id = _get_port_id(quantum, module, router_id, subnet_id)
         if not port_id:
-            module.exit_json(changed = False, result = "Sucess")
+            module.exit_json(changed = False, result = "Success")
         _remove_interface_router(quantum, module, router_id, subnet_id)
         module.exit_json(changed=True, result="Deleted")
                         
diff --git a/notification/mail b/notification/mail
index b3d9dc794fe..76d39cc6b27 100644
--- a/notification/mail
+++ b/notification/mail
@@ -103,7 +103,7 @@ options:
 
 EXAMPLES = '''
 # Example playbook sending mail to root
-- local_action: mail msg='System ${ansible_hostname} has been sucessfully provisioned.'
+- local_action: mail msg='System ${ansible_hostname} has been successfully provisioned.'
 
 # Send e-mail to a bunch of users, attaching files
 - local_action: mail

From c96e6c0d1d7f812ff0ed0d9e38ed4c9e3f4d6823 Mon Sep 17 00:00:00 2001
From: Joshua Lund <josh@joshlund.com>
Date: Tue, 18 Jun 2013 15:01:01 -0600
Subject: [PATCH 4/5] Removed merge conflict header

---
 network/get_url | 1 -
 1 file changed, 1 deletion(-)

diff --git a/network/get_url b/network/get_url
index 7cc1c5227ec..53b07261479 100644
--- a/network/get_url
+++ b/network/get_url
@@ -89,7 +89,6 @@ author: Jan-Piet Mens
 '''
 
 EXAMPLES='''
-<<<<<<< HEAD
 - name: download foo.conf
   get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf mode=0440
 

From 9f3c43290e1e864163f78d282fff17bc690b53c4 Mon Sep 17 00:00:00 2001
From: Jesse Keating <jesse.keating@rackspace.com>
Date: Tue, 18 Jun 2013 16:25:46 -0700
Subject: [PATCH 5/5] pkg option of apt is not required

You can use apt module with update_cache and without specifying a
package. Update the docs to reflect this.
---
 packaging/apt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packaging/apt b/packaging/apt
index dd2fed9e465..d0e86e80827 100644
--- a/packaging/apt
+++ b/packaging/apt
@@ -31,7 +31,7 @@ options:
   pkg:
     description:
       - A package name or package specifier with version, like C(foo) or C(foo=1.0)
-    required: true
+    required: false
     default: null
   state:
     description: