From 86bd318e41b0bec10765d0498a125de062afe1f9 Mon Sep 17 00:00:00 2001
From: Scott Moser <smoser@ubuntu.com>
Date: Fri, 9 Oct 2015 12:39:23 -0400
Subject: support configuring and installing the Ubuntu fan driver

  #cloud-config
  fan:
    config: |
      # fan 240
      10.0.0.0/8 eth0/16 dhcp
      10.0.0.0/8 eth1/16 dhcp off
      # fan 241
      241.0.0.0/8 eth0/16 dhcp
    config_path: /etc/network/fan

LP: #1504604
---
 ChangeLog                  |   1 +
 cloudinit/config/cc_fan.py | 101 +++++++++++++++++++++++++++++++++++++++++++++
 config/cloud.cfg           |   1 +
 3 files changed, 103 insertions(+)
 create mode 100644 cloudinit/config/cc_fan.py

diff --git a/ChangeLog b/ChangeLog
index bbb7e990..b7a66aa1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -62,6 +62,7 @@
  - reporting: add reporting module for web hook or logging of events.
  - NoCloud: fix consumption of vendordata (LP: #1493453)
  - power_state_change: support 'condition' to disable or enable poweroff
+ - ubuntu fan: support for config and installing of ubuntu fan (LP: #1504604)
 0.7.6:
  - open 0.7.6
  - Enable vendordata on CloudSigma datasource (LP: #1303986)
diff --git a/cloudinit/config/cc_fan.py b/cloudinit/config/cc_fan.py
new file mode 100644
index 00000000..39e3850e
--- /dev/null
+++ b/cloudinit/config/cc_fan.py
@@ -0,0 +1,101 @@
+# vi: ts=4 expandtab
+#
+#    Copyright (C) 2015 Canonical Ltd.
+#
+#    Author: Scott Moser <scott.moser@canonical.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/>.
+"""
+fan module allows configuration of Ubuntu Fan
+  https://wiki.ubuntu.com/FanNetworking
+
+Example config:
+  #cloud-config
+  fan:
+    config: |
+      # fan 240
+      10.0.0.0/8 eth0/16 dhcp
+      10.0.0.0/8 eth1/16 dhcp off
+      # fan 241
+      241.0.0.0/8 eth0/16 dhcp
+    config_path: /etc/network/fan
+
+If cloud-init sees a 'fan' entry in cloud-config it will
+ a.) write 'config_path' with the contents
+ b.) install the package 'ubuntu-fan' if it is not installed
+ c.) ensure the service is started (or restarted if was previously running)
+"""
+
+from cloudinit import log as logging
+from cloudinit import util
+from cloudinit.settings import PER_INSTANCE
+
+LOG = logging.getLogger(__name__)
+
+frequency = PER_INSTANCE
+
+BUILTIN_CFG = {
+    'config': None,
+    'config_path': '/etc/network/fan',
+}
+
+
+def stop_update_start(service, config_file, content, systemd=False):
+    if systemd:
+        cmds = {'stop': ['systemctl', 'stop', service],
+                'start': ['systemctl', 'start', service],
+                'enable': ['systemctl', 'enable', service]}
+    else:
+        cmds = {'stop': ['service', 'stop'],
+                'start': ['service', 'start']}
+
+    def run(cmd, msg):
+        try:
+            return util.subp(cmd, capture=True)
+        except util.ProcessExecutionError as e:
+            LOG.warn("failed: %s (%s): %s", service, cmd, e)
+            return False
+
+    stop_failed = not run(cmds['stop'], msg='stop %s' % service)
+    if not content.endswith('\n'):
+        content += '\n'
+    util.write_file(config_file, content, omode="w")
+
+    ret = run(cmds['start'], msg='start %s' % service)
+    if ret and stop_failed:
+        LOG.warn("success: %s started", service)
+
+    if 'enable' in cmds:
+        ret = run(cmds['enable'], msg='enable %s' % service)
+
+    return ret
+
+
+def handle(name, cfg, cloud, log, args):
+    cfgin = cfg.get('fan')
+    if not cfgin:
+        cfgin = {}
+    mycfg = util.mergemanydict([cfgin, BUILTIN_CFG])
+
+    if not mycfg.get('config'):
+        LOG.debug("%s: no 'fan' config entry. disabling", name)
+        return
+
+    util.write_file(mycfg.get('config_path'), mycfg.get('config'), omode="w")
+    distro = cloud.distro
+    if not util.which('fanctl'):
+        distro.install_packages(['ubuntu-fan'])
+
+    stop_update_start(
+        service='ubuntu-fan', config_file=mycfg.get('config_path'),
+        content=mycfg.get('config'), systemd=distro.uses_systemd())
diff --git a/config/cloud.cfg b/config/cloud.cfg
index 2b27f379..74794ab0 100644
--- a/config/cloud.cfg
+++ b/config/cloud.cfg
@@ -53,6 +53,7 @@ cloud_config_modules:
  - apt-pipelining
  - apt-configure
  - package-update-upgrade-install
+ - fan
  - landscape
  - timezone
  - puppet
-- 
cgit v1.2.3