Ori.livneh has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/108312


Change subject: Add misc::evergreen resource to refresh services on config 
updates
......................................................................

Add misc::evergreen resource to refresh services on config updates

If a role that writes its configuration to a recursively-managed foo.d/-type
directory is disabled, its configuration file will be purged, but the service
it configures will not necessarily be refreshed. This patch adds a
misc::evergreen resource that takes a service name and one or more paths to
search. If the most recent modification time of the path or any of the files or
directories within it is newer than the oldest instance of the service, the
service is automatically refreshed.

Change-Id: Ib969eb352461ab655d1b0f368c91e6737122f1c3
---
M puppet/modules/apache/manifests/init.pp
A puppet/modules/misc/files/check_service_freshness
A puppet/modules/misc/manifests/evergreen.pp
M puppet/modules/misc/manifests/init.pp
4 files changed, 116 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vagrant 
refs/changes/12/108312/1

diff --git a/puppet/modules/apache/manifests/init.pp 
b/puppet/modules/apache/manifests/init.pp
index 84a088c..cd96d06 100644
--- a/puppet/modules/apache/manifests/init.pp
+++ b/puppet/modules/apache/manifests/init.pp
@@ -35,4 +35,6 @@
         require    => Package['apache2'],
         hasrestart => true,
     }
+
+    misc::evergreen { 'apache2': }
 }
diff --git a/puppet/modules/misc/files/check_service_freshness 
b/puppet/modules/misc/files/check_service_freshness
new file mode 100755
index 0000000..d7c7cd4
--- /dev/null
+++ b/puppet/modules/misc/files/check_service_freshness
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+   check_service_freshness
+
+   Usage: check_service_freshness program_name config_path [config_path ...]
+   Example: check_service_freshness apache2 /etc/apache2
+
+   If the most recently-modified file in `config_path` is newer than the oldest
+   running process with `program_name` as its executable, set exit code to 1,
+   indicating that the service needs to be restarted to load the updated
+   configs. Otherwise set exit code to 0, indicating that the service is
+   up-to-date.
+
+"""
+import os
+import re
+import sys
+
+
+JIFFY = os.sysconf('SC_CLK_TCK')
+
+if len(sys.argv) < 3:
+    sys.stderr.write('Usage: %s program_name config_path [config_path ...]\n'
+                     % __file__)
+    sys.exit(126)
+
+program_name, config_paths = sys.argv[1], sys.argv[2:]
+
+
+def get_system_start():
+    """Get the system start time, expressed as seconds since epoch."""
+    with open('/proc/stat') as f:
+        match = re.search('(?<=btime )\d+', f.read())
+    return float(match.group(0))
+
+
+def iter_files(dir):
+    """Yields (path, mtime) for `dir` and each file or dir within it."""
+    yield dir, os.path.getmtime(dir)
+    for root, dirs, files in os.walk('/etc/apache2'):
+        for f in (dirs + files):
+            path = os.path.join(root, f)
+            yield path, os.path.getmtime(path)
+
+
+def iter_procs():
+    """Yields (executable name, start time) for each running process."""
+    system_start = get_system_start()
+    for pid in os.listdir('/proc'):
+        try:
+            with open('/proc/%s/stat' % pid) as f:
+                stats = f.read().split()
+                executable = stats[1].strip('()')
+                start_time = (float(stats[21]) / JIFFY) + system_start
+                yield executable, start_time
+        except (IOError, ValueError):
+            pass
+
+
+service_start = min(start_time for executable_name, start_time in iter_procs()
+                    if executable_name == program_name)
+latest_modification = max(modified_time for config_path in config_paths
+                          for path, modified_time in iter_files(config_path))
+
+if service_start < latest_modification:
+    # Service needs to be refreshed
+    sys.exit(1)
+else:
+    # Service is up-to-date
+    sys.exit(0)
diff --git a/puppet/modules/misc/manifests/evergreen.pp 
b/puppet/modules/misc/manifests/evergreen.pp
new file mode 100644
index 0000000..84ddcac
--- /dev/null
+++ b/puppet/modules/misc/manifests/evergreen.pp
@@ -0,0 +1,38 @@
+# == Define: misc::evergreen
+#
+# Refresh a service if its configuration files have changed.
+#
+# === Parameters
+#
+# [*service*]
+#   Service name. Defaults to the resource title.
+#
+# [*executable*]
+#   Base name of program's executable file. The process table will be
+#   scanned for processes matching this name to determine if the service
+#   needs to be refreshed. Defaults to the resource title.
+#
+# [*config_path*]
+#   Path to service's configuration directory. Defaults to /etc/$title.
+#   Multiple paths may be specified as an array.
+#
+# === Examples
+#
+#  misc::evergreen { 'apache2':
+#    config_path => '/etc/apache2',
+#  }
+#
+define misc::evergreen(
+    $service    = $title,
+    $executable = $title,
+    $config_path = "/etc/${title}",
+) {
+    include ::misc
+
+    exec { "check ${service} freshness":
+        command => '/bin/true',
+        unless  => "/usr/sbin/check_service_freshness ${executable} 
${config_path}",
+        require => File['/usr/sbin/check_service_freshness'],
+        notify  => Service[$service],
+    }
+}
diff --git a/puppet/modules/misc/manifests/init.pp 
b/puppet/modules/misc/manifests/init.pp
index 772e042..0dc67f3 100644
--- a/puppet/modules/misc/manifests/init.pp
+++ b/puppet/modules/misc/manifests/init.pp
@@ -49,6 +49,11 @@
         source => 'puppet:///modules/misc/mediawiki-vagrant.logrotate',
     }
 
+    file { '/usr/sbin/check_service_freshness':
+        source => 'puppet:///modules/misc/check_service_freshness',
+        mode   => '0755',
+    }
+
     # Look, I didn't pick the name..
     package { [ 'toilet', 'toilet-fonts' ]:
         ensure => present,

-- 
To view, visit https://gerrit.wikimedia.org/r/108312
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib969eb352461ab655d1b0f368c91e6737122f1c3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vagrant
Gerrit-Branch: master
Gerrit-Owner: Ori.livneh <o...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to