Filippo Giunchedi has uploaded a new change for review.

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

Change subject: swift: refactor into module, add codfw
......................................................................

swift: refactor into module, add codfw

The new module is aptly named not swift but swift_new, it is transitional only
however. Initially only codfw is on swift_new and other clusters will be
migrated to the new module once codfw is up and running. At that point the
module can be renamed into 'swift' and the legacy removed.

Change-Id: I265b586fb0e54cf1f0e5c1463813986f42b1dd12
---
M manifests/role/swift.pp
M manifests/site.pp
A modules/swift_new/files/.pep8
A modules/swift_new/files/swift-account-stats
A modules/swift_new/files/swift-dispersion-stats
A modules/swift_new/files/swift-drive-audit
A modules/swift_new/files/swift-drive-audit.conf
A modules/swift_new/files/swift-labs-ring
A modules/swift_new/files/swift-proxy.logrotate.conf
A modules/swift_new/files/swift-proxy.rsyslog.conf
A modules/swift_new/manifests/init.pp
A modules/swift_new/manifests/init_device.pp
A modules/swift_new/manifests/label_filesystem.pp
A modules/swift_new/manifests/mount_filesystem.pp
A modules/swift_new/manifests/proxy.pp
A modules/swift_new/manifests/proxy/monitoring.pp
A modules/swift_new/manifests/ring.pp
A modules/swift_new/manifests/stats.pp
A modules/swift_new/manifests/stats/accounts.pp
A modules/swift_new/manifests/stats/dispersion.pp
A modules/swift_new/manifests/stats/stats_account.pp
A modules/swift_new/manifests/storage.pp
A modules/swift_new/manifests/storage/monitoring.pp
A modules/swift_new/templates/account-server.conf.erb
A modules/swift_new/templates/container-server.conf.erb
A modules/swift_new/templates/dispersion.conf.erb
A modules/swift_new/templates/object-server.conf.erb
A modules/swift_new/templates/proxy-server.conf.erb
A modules/swift_new/templates/swift.conf.erb
29 files changed, 1,251 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/puppet 
refs/changes/91/162291/1

diff --git a/manifests/role/swift.pp b/manifests/role/swift.pp
index 96560f9..192b276 100644
--- a/manifests/role/swift.pp
+++ b/manifests/role/swift.pp
@@ -2,6 +2,7 @@
     description => 'swift servers',
 }
 
+
 class role::swift {
     class base {
         include standard
@@ -315,3 +316,138 @@
         priority => 1005,
     }
 }
+
+#######
+
+include passwords::swift::codfw_prod
+
+# swift accounts, each sub-hash contains a single account specification:
+# user: username specified as account:user (config files will change : with _)
+# key: password
+# auth: auth URL to get authentication tokens
+# access: account access level
+# account_name: internal account name, AUTH_<id>
+$codfw_prod_accounts = {
+    'super_admin' => {
+        'access'       => '.admin .reseller_admin',
+        'account_name' => 'AUTH_admin',
+        'auth'         => 'http://ms-fe.codfw.wmnet/auth/v1.0',
+        'key'          => $passwords::swift::codfw_prod::admin_password,
+        'user'         => 'admin:admin',
+    },
+    'mw_media' => {
+        'access'       => '.admin',
+        'account_name' => 'AUTH_mw',
+        'auth'         => 'http://ms-fe.codfw.wmnet/auth/v1.0',
+        'key'          => $passwords::swift::codfw_prod::rewrite_password,
+        'user'         => 'mw:media',
+    },
+    'dispersion' => {
+        'access'       => '.admin',
+        'account_name' => 'AUTH_dispersion',
+        'auth'         => 'http://ms-fe.codfw.wmnet/auth/v1.0',
+        'key'          => $passwords::swift::codfw_prod::dispersion_password,
+        'user'         => 'swift:dispersion',
+    },
+    'search_backup' => {
+        'access'       => '.admin',
+        'account_name' => 'AUTH_search',
+        'auth'         => 'http://ms-fe.codfw.wmnet/auth/v1.0',
+        'key'          => $passwords::swift::codfw_prod::search_password,
+        'user'         => 'search:backup',
+    },
+}
+
+# XXX refactor and split into wikipedia-$project-local-$type
+$shard_container_list = [
+    'global-data-math-render',
+    'wikipedia-commons-local-public', 'wikipedia-commons-local-temp', 
'wikipedia-commons-local-thumb', 'wikipedia-commons-local-transcoded',
+    'wikipedia-de-local-public', 'wikipedia-de-local-temp', 
'wikipedia-de-local-thumb', 'wikipedia-de-local-transcoded',
+    'wikipedia-en-local-public', 'wikipedia-en-local-temp', 
'wikipedia-en-local-thumb', 'wikipedia-en-local-transcoded',
+    'wikipedia-fi-local-public', 'wikipedia-fi-local-temp', 
'wikipedia-fi-local-thumb', 'wikipedia-fi-local-transcoded',
+    'wikipedia-fr-local-public', 'wikipedia-fr-local-temp', 
'wikipedia-fr-local-thumb', 'wikipedia-fr-local-transcoded',
+    'wikipedia-he-local-public', 'wikipedia-he-local-temp', 
'wikipedia-he-local-thumb', 'wikipedia-he-local-transcoded',
+    'wikipedia-hu-local-public', 'wikipedia-hu-local-temp', 
'wikipedia-hu-local-thumb', 'wikipedia-hu-local-transcoded',
+    'wikipedia-id-local-public', 'wikipedia-id-local-temp', 
'wikipedia-id-local-thumb', 'wikipedia-id-local-transcoded',
+    'wikipedia-it-local-public', 'wikipedia-it-local-temp', 
'wikipedia-it-local-thumb', 'wikipedia-it-local-transcoded',
+    'wikipedia-ja-local-public', 'wikipedia-ja-local-temp', 
'wikipedia-ja-local-thumb', 'wikipedia-ja-local-transcoded',
+    'wikipedia-ro-local-public', 'wikipedia-ro-local-temp', 
'wikipedia-ro-local-thumb', 'wikipedia-ro-local-transcoded',
+    'wikipedia-ru-local-public', 'wikipedia-ru-local-temp', 
'wikipedia-ru-local-thumb', 'wikipedia-ru-local-transcoded',
+    'wikipedia-th-local-public', 'wikipedia-th-local-temp', 
'wikipedia-th-local-thumb', 'wikipedia-th-local-transcoded',
+    'wikipedia-tr-local-public', 'wikipedia-tr-local-temp', 
'wikipedia-tr-local-thumb', 'wikipedia-tr-local-transcoded',
+    'wikipedia-uk-local-public', 'wikipedia-uk-local-temp', 
'wikipedia-uk-local-thumb', 'wikipedia-uk-local-transcoded',
+    'wikipedia-zh-local-public', 'wikipedia-zh-local-temp', 
'wikipedia-zh-local-thumb', 'wikipedia-zh-local-transcoded',
+]
+
+class role::swift::codfw-prod::stats_reporter {
+    class {'swift_new::stats': }
+
+    class {'swift_new::stats::dispersion':
+        cluster => 'codfw-prod',
+    }
+
+    class {'swift_new::stats::accounts':
+        cluster  => 'codfw-prod',
+        accounts => $codfw_prod_accounts,
+    }
+}
+
+class role::swift::codfw-prod::proxy {
+    class {'swift_new':
+        cluster          => 'codfw-prod',
+        hash_path_suffix => 'de4227064232ed08',
+    }
+
+    class {'swift_new::ring':
+        cluster => 'codfw-prod',
+    }
+
+    class {'swift_new::proxy::monitoring':
+        host => 'ms-fe.codfw.wmnet',
+    }
+
+    class {'swift_new::proxy':
+        proxy_address        => 'http://ms-fe.codfw.wmnet',
+        memcached_servers    => ['ms-fe2001.eqiad.wmnet:11211'],
+        rewrite_thumb_server => 'rendering.svc.eqiad.wmnet',
+        shard_container_list => $shard_container_list,
+        accounts             => $codfw_prod_accounts,
+        dispersion_account   => $codfw_prod_accounts['dispersion'],
+        rewrite_account      => $codfw_prod_accounts['mw_media'],
+    }
+
+    class { '::memcached':
+        memcached_size => '128',
+        memcached_port => '11211',
+    }
+}
+
+class role::swift::codfw-prod::storage {
+    class {'swift_new':
+        cluster          => 'codfw-prod',
+        hash_path_suffix => 'de4227064232ed08',
+    }
+
+    class {'swift_new::ring':
+        cluster => 'codfw-prod',
+    }
+
+    class {'swift_new::storage::monitoring':
+    }
+
+    class {'swift_new::storage':
+    }
+
+    $all_drives = [
+        '/dev/sda', '/dev/sdb', '/dev/sdc', '/dev/sdd',
+        '/dev/sde', '/dev/sdf', '/dev/sdg', '/dev/sdh',
+        '/dev/sdi', '/dev/sdj', '/dev/sdk', '/dev/sdl'
+    ]
+
+    swift_new::init_device{ $all_drives: partition_nr => '1' }
+    # these are already partitioned and xfs formatted by the installer
+    swift_new::label_filesystem{ '/dev/sdm3': }
+    swift_new::label_filesystem{ '/dev/sdn3': }
+    swift_new::mount_filesystem{ '/dev/sdm3': }
+    swift_new::mount_filesystem{ '/dev/sdn3': }
+}
diff --git a/manifests/site.pp b/manifests/site.pp
index ef6a360..fb105aa 100644
--- a/manifests/site.pp
+++ b/manifests/site.pp
@@ -2111,6 +2111,34 @@
     swift::mount_filesystem{ '/dev/sdb3': }
 }
 
+node /^ms-fe200[1-4]\.codfw\.wmnet$/ {
+    include admin
+
+    $cluster = 'swift'
+    $nagios_group = 'swift'
+    if $::hostname =~ /^ms-fe200[12]$/ {
+        $ganglia_aggregator = true
+    }
+
+    if $::hostname == 'ms-fe2001' {
+        include role::swift::codfw-prod::stats_reporter
+    }
+
+    # XXX update with codfw service address
+    #class { 'lvs::realserver': realserver_ips => [ '10.2.2.27' ] }
+
+    include role::swift::codfw-prod::proxy
+}
+
+node /^ms-be20[0-9][0-9]\.codfw\.wmnet$/ {
+    include admin
+
+    $cluster = 'swift'
+    $nagios_group = 'swift'
+
+    include role::swift::codfw-prod::storage
+}
+
 # mw1001-1016 are jobrunners (precise)
 node /^mw10(0[1-9]|1[0-6])\.eqiad\.wmnet$/ {
 
diff --git a/modules/swift_new/files/.pep8 b/modules/swift_new/files/.pep8
new file mode 100644
index 0000000..16c865a
--- /dev/null
+++ b/modules/swift_new/files/.pep8
@@ -0,0 +1,6 @@
+[pep8]
+
+# Suppress warnings:
+# E501: line too long
+# E221: multiple spaces before operator
+ignore = E501,E241
diff --git a/modules/swift_new/files/swift-account-stats 
b/modules/swift_new/files/swift-account-stats
new file mode 100755
index 0000000..c4a8894
--- /dev/null
+++ b/modules/swift_new/files/swift-account-stats
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+
+# report swift account statistics, by default on stdout and optionally to
+# a statsd server via UDP
+# optionally, report statistics for every container found for the given
+# account.
+
+import argparse
+import os
+import sys
+
+import swiftclient
+
+try:
+    import statsd
+    statsd_found = True
+except ImportError:
+    statsd_found = False
+
+
+def main():
+    parser = argparse.ArgumentParser(description="Print swift account 
statistics")
+    parser.add_argument('-A', '--auth', dest='auth',
+        default=os.environ.get('ST_AUTH', None),
+        help='URL for obtaining an auth token')
+    parser.add_argument('-U', '--user', dest='user',
+        default=os.environ.get('ST_USER', None),
+        help='User name for obtaining an auth token')
+    parser.add_argument('-K', '--key', dest='key',
+        default=os.environ.get('ST_KEY', None),
+        help='Key for obtaining an auth token')
+    parser.add_argument('--prefix', dest='prefix',
+        default='',
+        help='Prefix to use with the metrics')
+    parser.add_argument('--show-containers', dest='show_containers',
+        default=False, action='store_true',
+        help='Prefix to use with the metrics')
+    parser.add_argument('--statsd-host', dest='statsd_host',
+        default='', metavar="HOST",
+        help='Send metrics to this statsd host as well')
+    parser.add_argument('--statsd-port', dest='statsd_port',
+        default='8125', metavar="PORT", type=int,
+        help='Send metrics to this statsd port')
+    args = parser.parse_args()
+
+    if None in (args.auth, args.user, args.key):
+        parser.error("please provide auth, user and key")
+        return 1
+
+    account_stats = {}
+    container_stats = {}
+    output_stats = []
+
+    connection = swiftclient.Connection(args.auth, args.user, args.key)
+    headers = connection.head_account()
+    account_stats = {
+        'containers': headers['x-account-container-count'],
+        'objects': headers['x-account-object-count'],
+        'bytes': headers['x-account-bytes-used'],
+    }
+
+    if args.show_containers:
+        headers, containers = connection.get_account(full_listing=True)
+        for container in containers:
+            container_stats[container['name']] = {
+               'bytes': container['bytes'],
+               'objects': container['count'],
+            }
+
+    for key, value in account_stats.iteritems():
+        prefix = '.'.join([args.prefix, key])
+        output_stats.append((prefix, value))
+
+    if args.show_containers:
+        for name, stats in container_stats.iteritems():
+            for key, value in stats.iteritems():
+                prefix = '.'.join([args.prefix, 'container', name, key])
+                output_stats.append((prefix, value))
+
+    for name, value in output_stats:
+        print "%s: %s" % (name, value)
+
+    if args.statsd_host:
+        if not statsd_found:
+            print >>sys.stderr, "statsd module not found, unable to send"
+            return 1
+        client = statsd.StatsClient(args.statsd_host, args.statsd_port)
+        for name, value in output_stats:
+            try:
+                client.gauge(name, float(value))
+            except ValueError:
+                print >>sys.stderr, "failed to send %r %r" % (name, value)
+
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/modules/swift_new/files/swift-dispersion-stats 
b/modules/swift_new/files/swift-dispersion-stats
new file mode 100755
index 0000000..c4d5eba
--- /dev/null
+++ b/modules/swift_new/files/swift-dispersion-stats
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+# report swift dispersion statistics, by default on stdout and optionally to
+# a statsd server via UDP
+
+import argparse
+import json
+import os
+import subprocess
+import sys
+
+try:
+    import statsd
+    statsd_found = True
+except ImportError:
+    statsd_found = False
+
+
+def main():
+    parser = argparse.ArgumentParser(description="Print swift dispersion 
statistics")
+    parser.add_argument('--prefix', dest='prefix', default='',
+                        help='Prefix to use with the metrics')
+    parser.add_argument('--statsd-host', dest='statsd_host', default='', 
metavar="HOST",
+                        help='Send metrics to this statsd host as well')
+    parser.add_argument('--statsd-port', dest='statsd_port', default='8125',
+                        metavar="PORT", type=int, help='Send metrics to this 
statsd port')
+    args = parser.parse_args()
+
+    dispersion_stats = {}
+
+    try:
+        output = subprocess.check_output(['swift-dispersion-report', '-j'])
+    except subprocess.CalledProcessError, e:
+        print >>sys.stderr, 'swift-dispersion-report failed %s: %r' % (
+            e.returncode, e.output)
+        return e.returncode
+
+    try:
+        json_stats = json.loads(output)
+    except ValueError, e:
+        print >>sys.stderr, 'failed to load json from %r' % output
+        return 1
+
+    # {"object": {
+    #    "retries": 0, "missing_0": 1304, "copies_expected": 2608,
+    #    "pct_found": 100.0, "overlapping": 6, "copies_found": 2608
+    #   },
+    #  "container": {
+    #    "retries": 0, "copies_expected": 2606, "pct_found": 100.0,
+    #    "overlapping": 8, "copies_found": 2606
+    #   }}
+    for ring, stat in json_stats.iteritems():
+        for name, value in stat.iteritems():
+            key = '.'.join([args.prefix, ring, name])
+            dispersion_stats[key] = value
+
+    for key, value in dispersion_stats.iteritems():
+        print "%s: %s" % (key, value)
+
+    if args.statsd_host:
+        if not statsd_found:
+            print >>sys.stderr, "statsd module not found, unable to send"
+            return 1
+        client = statsd.StatsClient(args.statsd_host, args.statsd_port)
+        for key, value in dispersion_stats.iteritems():
+            try:
+                client.gauge(key, float(value))
+            except ValueError:
+                print >>sys.stderr, "failed to send %r %r" % (key, value)
+
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/modules/swift_new/files/swift-drive-audit 
b/modules/swift_new/files/swift-drive-audit
new file mode 100755
index 0000000..5481f09
--- /dev/null
+++ b/modules/swift_new/files/swift-drive-audit
@@ -0,0 +1,201 @@
+#!/usr/bin/python
+# Copyright (c) 2010-2012 OpenStack Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Upon exit, the following will be bitwise OR-ed:
+# EX_OK: no errors found in log files
+# 2: a device was unmounted
+# 4: a device was unavailable while unmounting
+
+import datetime
+import glob
+import os
+import re
+import subprocess
+import sys
+from ConfigParser import ConfigParser
+
+from swift.common.utils import backward, get_logger
+
+EX_DEV_UNMOUNTED = 2
+EX_DEV_UNAVAILABLE = 4
+
+
+def get_devices(device_dir, logger):
+    devices = []
+    for line in open('/proc/mounts').readlines():
+        data = line.strip().split()
+        block_device = data[0]
+        mount_point = data[1]
+        if mount_point.startswith(device_dir):
+            device = {}
+            device['mount_point'] = mount_point
+            device['block_device'] = block_device
+            try:
+                device_num = os.stat(block_device).st_rdev
+            except OSError:
+                # If we can't stat the device, then something weird is going on
+                logger.error("Error: Could not stat %s!" %
+                             block_device)
+                continue
+            device['major'] = str(os.major(device_num))
+            device['minor'] = str(os.minor(device_num))
+            devices.append(device)
+    for line in open('/proc/partitions').readlines()[2:]:
+        major, minor, blocks, kernel_device = line.strip().split()
+        device = [d for d in devices
+                  if d['major'] == major and d['minor'] == minor]
+        if device:
+            device[0]['kernel_device'] = kernel_device
+    return devices
+
+
+def get_errors(error_re, log_file_pattern, minutes):
+    # Assuming log rotation is being used, we need to examine
+    # recently rotated files in case the rotation occurred
+    # just before the script is being run - the data we are
+    # looking for may have rotated.
+    #
+    # The globbing used before would not work with all out-of-box
+    # distro setup for logrotate and syslog therefore moving this
+    # to the config where one can set it with the desired
+    # globbing pattern.
+    log_files = [f for f in glob.glob(log_file_pattern)]
+    log_files.sort()
+
+    now_time = datetime.datetime.now()
+    end_time = now_time - datetime.timedelta(minutes=minutes)
+    # kern.log does not contain the year so we need to keep
+    # track of the year and month in case the year recently
+    # ticked over
+    year = now_time.year
+    prev_entry_month = now_time.month
+    errors = {}
+
+    reached_old_logs = False
+    for path in log_files:
+        try:
+            f = open(path)
+        except IOError:
+            logger.error("Error: Unable to open " + path)
+            print("Unable to open " + path)
+            sys.exit(os.EX_OSFILE)
+        for line in backward(f):
+            if '[    0.000000]' in line \
+                or 'KERNEL supported cpus:' in line \
+                    or 'BIOS-provided physical RAM map:' in line:
+                # Ignore anything before the last boot
+                reached_old_logs = True
+                break
+            # Solves the problem with year change - kern.log does not
+            # keep track of the year.
+            log_time_entry = line.split()[:3]
+            if log_time_entry[0] == 'Dec' and prev_entry_month == 'Jan':
+                year -= 1
+            prev_entry_month = log_time_entry[0]
+            log_time_string = '%s %s' % (year, ' '.join(log_time_entry))
+            try:
+                log_time = datetime.datetime.strptime(
+                    log_time_string, '%Y %b %d %H:%M:%S')
+            except ValueError:
+                continue
+            if log_time > end_time:
+                for err in error_re:
+                    for device in err.findall(line):
+                        errors[device] = errors.get(device, 0) + 1
+            else:
+                reached_old_logs = True
+                break
+        if reached_old_logs:
+            break
+    return errors
+
+
+def comment_fstab(mount_point):
+    with open('/etc/fstab', 'r') as fstab:
+        with open('/etc/fstab.new', 'w') as new_fstab:
+            for line in fstab:
+                parts = line.split()
+                if len(parts) > 2 and line.split()[1] == mount_point:
+                    new_fstab.write('#' + line)
+                else:
+                    new_fstab.write(line)
+    os.rename('/etc/fstab.new', '/etc/fstab')
+
+
+if __name__ == '__main__':
+    c = ConfigParser()
+    try:
+        conf_path = sys.argv[1]
+    except Exception:
+        print "Usage: %s CONF_FILE" % sys.argv[0].split('/')[-1]
+        sys.exit(os.EX_USAGE)
+    if not c.read(conf_path):
+        print "Unable to read config file %s" % conf_path
+        sys.exit(os.EX_CONFIG)
+    conf = dict(c.items('drive-audit'))
+    device_dir = conf.get('device_dir', '/srv/node')
+    minutes = int(conf.get('minutes', 60))
+    error_limit = int(conf.get('error_limit', 1))
+    log_file_pattern = conf.get('log_file_pattern',
+                                '/var/log/kern.*[!.][!g][!z]')
+    error_re = []
+    for conf_key in conf:
+        if conf_key.startswith('regex_pattern_'):
+            error_pattern = conf[conf_key]
+            try:
+                r = re.compile(error_pattern)
+            except re.error:
+                logger.error('Error: unable to compile regex pattern "%s"' %
+                             error_pattern)
+                sys.exit(os.EX_DATAERR)
+            error_re.append(r)
+    if not error_re:
+        error_re = [
+            re.compile(r'\berror\b.*\b(sd[a-z]{1,2}\d?)\b'),
+            re.compile(r'\b(sd[a-z]{1,2}\d?)\b.*\berror\b'),
+        ]
+    conf['log_name'] = conf.get('log_name', 'drive-audit')
+    logger = get_logger(conf, log_route='drive-audit')
+    devices = get_devices(device_dir, logger)
+    logger.debug("Devices found: %s" % str(devices))
+    if not devices:
+        logger.error("Error: No devices found!")
+    errors = get_errors(error_re, log_file_pattern, minutes)
+    logger.debug("Errors found: %s" % str(errors))
+    unmounts = 0
+    exitcode = os.EX_OK
+    for kernel_device, count in errors.items():
+        if count >= error_limit:
+            device = \
+                [d for d in devices if d['kernel_device'] == kernel_device]
+            if not device:
+                exitcode = exitcode | EX_DEV_UNAVAILABLE
+                logger.info("Errors found but device unavailable: %s:%s" %
+                            (kernel_device, count))
+                continue
+            mount_point = device[0]['mount_point']
+            if mount_point.startswith(device_dir):
+                logger.info("Unmounting %s with %d errors" %
+                            (mount_point, count))
+                subprocess.call(['umount', '-fl', mount_point])
+                logger.info("Commenting out %s from /etc/fstab" %
+                            (mount_point))
+                comment_fstab(mount_point)
+                unmounts += 1
+                exitcode = exitcode | EX_DEV_UNMOUNTED
+    if unmounts == 0:
+        logger.info("No drives were unmounted")
+    sys.exit(exitcode)
diff --git a/modules/swift_new/files/swift-drive-audit.conf 
b/modules/swift_new/files/swift-drive-audit.conf
new file mode 100644
index 0000000..b8964a4
--- /dev/null
+++ b/modules/swift_new/files/swift-drive-audit.conf
@@ -0,0 +1,3 @@
+[drive-audit]
+device_dir = /srv/swift-storage/
+
diff --git a/modules/swift_new/files/swift-labs-ring 
b/modules/swift_new/files/swift-labs-ring
new file mode 100644
index 0000000..416d792
--- /dev/null
+++ b/modules/swift_new/files/swift-labs-ring
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+set -e
+set -u
+
+partpower=${PARTPOWER:-18}
+replicas=${REPLICAS:-2}
+min_part_hours=${MIN_PART_HOURS:-1}
+device=${DEVICE:-swiftstore}
+weight=${WEIGHT:-100}
+
+
+function _missing_device() {
+  local ring=$1
+  local device=$2
+  out=$(swift-ring-builder $ring search $device)
+  [ $? -eq 2 ]
+}
+
+
+for ring in account container object; do
+  [ -e "${ring}.builder" ] && continue
+  swift-ring-builder ${ring}.builder create ${partpower} ${replicas} 
${min_part_hours}
+done
+
+
+zone=0
+for host in $*; do
+  echo "adding $host in zone $zone"
+  # no port used to search the device inside the ring, not needed
+  devicesearch="z${zone}-${host}/${device}"
+  _missing_device object.builder "$devicesearch" && \
+    swift-ring-builder object.builder add z${zone}-${host}:6000/${device} 
${weight}
+  _missing_device container.builder "$devicesearch" && \
+    swift-ring-builder container.builder add z${zone}-${host}:6001/${device} 
${weight}
+  _missing_device account.builder "$devicesearch" && \
+    swift-ring-builder account.builder add z${zone}-${host}:6002/${device} 
${weight}
+  zone=$(( $zone + 1 ))
+done
+
+
+for ring in account container object; do
+  swift-ring-builder ${ring}.builder rebalance
+done
diff --git a/modules/swift_new/files/swift-proxy.logrotate.conf 
b/modules/swift_new/files/swift-proxy.logrotate.conf
new file mode 100644
index 0000000..632d662
--- /dev/null
+++ b/modules/swift_new/files/swift-proxy.logrotate.conf
@@ -0,0 +1,12 @@
+/var/log/swift-access.log
+{
+    rotate 7
+    daily
+    missingok
+    notifempty
+    delaycompress
+    compress
+    postrotate
+        reload rsyslog >/dev/null 2>&1 || true
+    endscript
+}
diff --git a/modules/swift_new/files/swift-proxy.rsyslog.conf 
b/modules/swift_new/files/swift-proxy.rsyslog.conf
new file mode 100644
index 0000000..7839ab8
--- /dev/null
+++ b/modules/swift_new/files/swift-proxy.rsyslog.conf
@@ -0,0 +1,4 @@
+if $syslogfacility-text == 'local1' \
+  and $programname == 'proxy-server' \
+    then /var/log/swift-access.log
+& ~
diff --git a/modules/swift_new/manifests/init.pp 
b/modules/swift_new/manifests/init.pp
new file mode 100644
index 0000000..ca88b2b
--- /dev/null
+++ b/modules/swift_new/manifests/init.pp
@@ -0,0 +1,51 @@
+# XXX support additional storage policies
+class swift_new (
+    $cluster,
+    $hash_path_suffix,
+) {
+    include webserver::base
+
+    # Recommendations from Swift -- see <http://tinyurl.com/swift-sysctl>.
+    sysctl::parameters { 'swift_performance':
+        values => {
+            'net.ipv4.tcp_syncookies'             => '0',
+            'net.ipv4.tcp_tw_recycle'             => '1',  # disable TIME_WAIT
+            'net.ipv4.tcp_tw_reuse'               => '1',
+            'net.ipv4.netfilter.ip_conntrack_max' => '262144',
+        },
+    }
+
+    package { [
+        'swift',
+        'python-swift',
+        'python-swiftclient',
+        'python-statsd',
+        'parted',
+    ]:
+        ensure => 'present',
+    }
+
+    File {
+        owner => 'swift',
+        group => 'swift',
+        mode  => '0440',
+    }
+
+    file { '/etc/swift':
+        ensure  => 'directory',
+        require => Package['swift'],
+        recurse => true,
+    }
+
+    file { '/etc/swift/swift.conf':
+        ensure  => present,
+        require => Package['swift'],
+        content => template('swift_new/swift.conf.erb'),
+    }
+
+    file { '/var/cache/swift':
+        ensure  => 'directory',
+        require => Package['swift'],
+        mode    => '0755',
+    }
+}
diff --git a/modules/swift_new/manifests/init_device.pp 
b/modules/swift_new/manifests/init_device.pp
new file mode 100644
index 0000000..95685c6
--- /dev/null
+++ b/modules/swift_new/manifests/init_device.pp
@@ -0,0 +1,35 @@
+define swift_new::init_device($partition_nr='1') {
+    require base::platform
+
+    if (! $title =~ /^\/dev\/([hvs]d[a-z]+|md[0-9]+)$/) {
+        fail("unable to init ${title} for swift")
+    }
+
+    $dev           = "${title}${partition_nr}"
+    $dev_suffix    = regsubst($dev, '^\/dev\/(.*)$', '\1')
+    $fs_label      = "swift-${dev_suffix}"
+    $parted_cmd    = "parted --script --align optimal ${title}"
+    $parted_script = "mklabel gpt mkpart ${fs_label} 0 100%"
+    $mkfs_cmd      = "mkfs -t xfs -i size=512 ${dev}"
+
+    exec { "parted-${title}":
+        path    => '/usr/bin:/bin:/usr/sbin:/sbin',
+        require => Package['parted'],
+        command => "${parted_cmd} ${parted_script}",
+        creates => $dev,
+    }
+
+    exec { "mkfs-${title}":
+        command => $mkfs_cmd,
+        path    => '/sbin/:/usr/sbin/',
+        require => Package['xfsprogs'],
+        before  => Exec["parted-${title}"],
+        unless  => "xfs_admin -l ${title}",
+    }
+
+    swift_new::label_filesystem { $dev:
+        before => Exec["mkfs-${title}"],
+    }
+
+    swift_new::mount_filesystem { $dev: }
+}
diff --git a/modules/swift_new/manifests/label_filesystem.pp 
b/modules/swift_new/manifests/label_filesystem.pp
new file mode 100644
index 0000000..65a7cee
--- /dev/null
+++ b/modules/swift_new/manifests/label_filesystem.pp
@@ -0,0 +1,12 @@
+define swift_new::label_filesystem {
+    $dev        = $title
+    $dev_suffix = regsubst($dev, '^\/dev\/(.*)$', '\1')
+    $fs_label   = "swift-${dev_suffix}"
+
+    exec { "fs_label-${dev}":
+        command => "xfs_admin -L ${fs_label} ${dev}",
+        path    => '/usr/sbin:/usr/bin:/sbin:/bin',
+        require => Package['xfsprogs'],
+        unless  => "xfs_admin -l ${dev} | grep -q ${fs_label}"
+    }
+}
diff --git a/modules/swift_new/manifests/mount_filesystem.pp 
b/modules/swift_new/manifests/mount_filesystem.pp
new file mode 100644
index 0000000..4b9c13b
--- /dev/null
+++ b/modules/swift_new/manifests/mount_filesystem.pp
@@ -0,0 +1,26 @@
+define swift_new::mount_filesystem (
+    $mount_base = '/srv/swift-storage',
+){
+    $dev         = $title
+    $dev_suffix  = regsubst($dev, '^\/dev\/(.*)$', '\1')
+    $mount_point = "${mount_base}/${dev_suffix}"
+
+    file { "mountpoint-${mount_point}":
+        ensure => 'directory',
+        path   => $mount_point,
+        owner  => 'swift',
+        group  => 'swift',
+        mode   => '0750',
+    }
+
+    mount { $mount_point:
+        # XXX this won't mount the disks the first time they are added to fstab
+        ensure   => 'present',
+        device   => "LABEL=swift-${dev_suffix}",
+        name     => $mount_point,
+        fstype   => 'xfs',
+        options  => 'noatime,nodiratime,nobarrier,logbufs=8',
+        atboot   => true,
+        remounts => true,
+    }
+}
diff --git a/modules/swift_new/manifests/proxy.pp 
b/modules/swift_new/manifests/proxy.pp
new file mode 100644
index 0000000..f4aedd9
--- /dev/null
+++ b/modules/swift_new/manifests/proxy.pp
@@ -0,0 +1,65 @@
+class swift_new::proxy (
+    $proxy_address,
+    $rewrite_thumb_server,
+    $shard_container_list,
+    $accounts,
+    $memcached_servers         = ['localhost:11211'],
+    $statsd_host               = undef,
+    $statsd_metric_prefix      = undef,
+    $statsd_sample_rate_factor = '1',
+    $bind_port                 = '80',
+    $num_workers               = $::processorcount,
+    $backend_url_format        = 'sitelang',
+    $rewrite_account           = undef,
+    $dispersion_account        = undef,
+) {
+    system::role { 'swift::proxy':
+        description => 'swift frontend proxy',
+    }
+
+    package {[
+        'swift-proxy',
+        'python-swauth',
+    ]:
+        ensure => 'present',
+    }
+
+    file { '/etc/swift/proxy-server.conf':
+        owner   => 'swift',
+        group   => 'swift',
+        mode    => '0440',
+        content => template('swift_new/proxy-server.conf.erb'),
+        require => Package['swift-proxy'],
+    }
+
+    if $dispersion_account != undef {
+        file { '/etc/swift/dispersion.conf':
+            owner   => 'swift',
+            group   => 'swift',
+            mode    => '0440',
+            content => template('swift_new/dispersion.conf.erb'),
+            require => Package['swift'],
+        }
+    }
+
+    file { '/etc/logrotate.d/swift-proxy':
+        ensure => present,
+        source => 'puppet:///modules/swift_new/swift-proxy.logrotate.conf',
+        mode   => '0444',
+    }
+
+    rsyslog::conf { 'swift-proxy':
+        source   => 'puppet:///modules/swift_new/swift-proxy.rsyslog.conf',
+        priority => 30,
+    }
+
+    file { '/usr/local/lib/python2.7/dist-packages/wmf/':
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0444',
+        # XXX exception :(
+        # this still lives in files/ to avoid code duplication
+        source  => 'puppet:///files/swift/SwiftMedia/wmf/',
+        recurse => 'remote',
+    }
+}
diff --git a/modules/swift_new/manifests/proxy/monitoring.pp 
b/modules/swift_new/manifests/proxy/monitoring.pp
new file mode 100644
index 0000000..ac564b6
--- /dev/null
+++ b/modules/swift_new/manifests/proxy/monitoring.pp
@@ -0,0 +1,10 @@
+class swift_new::proxy::monitoring($host) {
+    monitor_service { 'swift-http-frontend':
+        description   => 'Swift HTTP frontend',
+        check_command => "check_http_url!${host}!/monitoring/frontend",
+    }
+    monitor_service { 'swift-http-backend':
+        description   => 'Swift HTTP backend',
+        check_command => "check_http_url!${host}!/monitoring/backend",
+    }
+}
diff --git a/modules/swift_new/manifests/ring.pp 
b/modules/swift_new/manifests/ring.pp
new file mode 100644
index 0000000..a78e359
--- /dev/null
+++ b/modules/swift_new/manifests/ring.pp
@@ -0,0 +1,34 @@
+# XXX support additional storage policies
+class swift_new::ring (
+    $cluster,
+) {
+    file { '/etc/swift/account.builder':
+        ensure => 'present',
+        source => "puppet:///volatile/swift/${cluster}/account.builder",
+    }
+
+    file { '/etc/swift/account.ring.gz':
+        ensure => 'present',
+        source => "puppet:///volatile/swift/${cluster}/account.ring.gz",
+    }
+
+    file { '/etc/swift/container.builder':
+        ensure => 'present',
+        source => "puppet:///volatile/swift/${cluster}/container.builder",
+    }
+
+    file { '/etc/swift/container.ring.gz':
+        ensure => 'present',
+        source => "puppet:///volatile/swift/${cluster}/container.ring.gz",
+    }
+
+    file { '/etc/swift/object.builder':
+        ensure => 'present',
+        source => "puppet:///volatile/swift/${cluster}/object.builder",
+    }
+
+    file { '/etc/swift/object.ring.gz':
+        ensure => 'present',
+        source => "puppet:///volatile/swift/${cluster}/object.ring.gz",
+    }
+}
diff --git a/modules/swift_new/manifests/stats.pp 
b/modules/swift_new/manifests/stats.pp
new file mode 100644
index 0000000..50be75c
--- /dev/null
+++ b/modules/swift_new/manifests/stats.pp
@@ -0,0 +1,5 @@
+class swift_new::stats {
+    system::role { 'swift::stats_reporter':
+        description => 'swift cluster statistics reporter',
+    }
+}
diff --git a/modules/swift_new/manifests/stats/accounts.pp 
b/modules/swift_new/manifests/stats/accounts.pp
new file mode 100644
index 0000000..148d63b
--- /dev/null
+++ b/modules/swift_new/manifests/stats/accounts.pp
@@ -0,0 +1,29 @@
+class swift_new::stats::accounts(
+    $cluster,
+    $accounts,
+    $statsd_host = 'statsd.eqiad.wmnet',
+    $statsd_prefix = "swift.${cluster}.stats",
+) {
+    $required_packages = [
+        Package['python-swiftclient'],
+        Package['python-statsd'],
+        Package['swift'],
+        ]
+
+    # report account stats to graphite
+    file { '/usr/local/bin/swift-account-stats':
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0555',
+        source  => 'puppet:///modules/swift_new/swift-account-stats',
+        require => $required_packages,
+    }
+
+    $account_names = keys($accounts)
+    swift_new::stats::stats_account { $account_names:
+        accounts      => $accounts,
+        statsd_prefix => $statsd_prefix,
+        statsd_host   => $statsd_host,
+    }
+}
diff --git a/modules/swift_new/manifests/stats/dispersion.pp 
b/modules/swift_new/manifests/stats/dispersion.pp
new file mode 100644
index 0000000..f79cb20
--- /dev/null
+++ b/modules/swift_new/manifests/stats/dispersion.pp
@@ -0,0 +1,30 @@
+class swift_new::stats::dispersion(
+    $cluster,
+    $statsd_host   = 'statsd.eqiad.wmnet',
+    $statsd_prefix = "swift.${cluster}.dispersion",
+) {
+    $required_packages = [
+        Package['python-swiftclient'],
+        Package['python-statsd'],
+        Package['swift'],
+    ]
+
+    file { '/usr/local/bin/swift-dispersion-stats':
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0555',
+        source  => 'puppet:///modules/swift_new/swift-dispersion-stats',
+        require => $required_packages,
+    }
+
+    # XXX swift-dispersion-populate is not ran/initialized
+    cron { 'swift-dispersion-stats':
+        ensure  => present,
+        command => "/usr/local/bin/swift-dispersion-stats --prefix 
${statsd_prefix} --statsd-host ${statsd_host} 1>/dev/null",
+        user    => 'root',
+        hour    => '*',
+        minute  => '*/15',
+        require => File['/usr/local/bin/swift-dispersion-stats'],
+    }
+}
diff --git a/modules/swift_new/manifests/stats/stats_account.pp 
b/modules/swift_new/manifests/stats/stats_account.pp
new file mode 100644
index 0000000..6e3a6a7
--- /dev/null
+++ b/modules/swift_new/manifests/stats/stats_account.pp
@@ -0,0 +1,32 @@
+define swift_new::stats::stats_account (
+    $accounts,
+    $statsd_prefix,
+    $statsd_host,
+) {
+    $account_info = $accounts[$name]
+    $auth_url     = $account_info[auth]
+    $user         = $account_info[user]
+    $key          = $account_info[key]
+    $account_name = $account_info[account_name]
+
+    $account_file = "/etc/swift/account_${account_name}.env"
+    $account_statsd_prefix = "${statsd_prefix}.${account_name}"
+
+    file { $account_file:
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0440',
+        content => "export ST_AUTH=${auth_url}\nexport ST_USER=${user}\nexport 
ST_KEY=${key}\n"
+    }
+
+    cron { "swift-account-stats_${user}":
+        ensure  => present,
+        command => ". ${account_file} && /usr/local/bin/swift-account-stats 
--prefix ${account_statsd_prefix} --statsd-host ${statsd_host} 1>/dev/null",
+        user    => 'root',
+        hour    => '*',
+        minute  => '*',
+        require => [File[$account_file],
+                    File['/usr/local/bin/swift-account-stats']],
+    }
+}
+
diff --git a/modules/swift_new/manifests/storage.pp 
b/modules/swift_new/manifests/storage.pp
new file mode 100644
index 0000000..168154e
--- /dev/null
+++ b/modules/swift_new/manifests/storage.pp
@@ -0,0 +1,115 @@
+class swift_new::storage {
+    system::role { 'swift::storage':
+        description => 'swift backend storage brick',
+    }
+
+    package {
+        [ 'swift-account',
+          'swift-container',
+          'swift-object',
+    ]:
+        ensure => 'present',
+    }
+
+    class { 'rsync::server':
+        log_file => '/var/log/rsyncd.log',
+    }
+
+    rsync::server::module {
+    'account':
+        uid             => 'swift',
+        gid             => 'swift',
+        max_connections => '5',
+        path            => '/srv/swift-storage/',
+        read_only       => 'no',
+        lock_file       => '/var/lock/account.lock';
+    'container':
+        uid             => 'swift',
+        gid             => 'swift',
+        max_connections => '5',
+        path            => '/srv/swift-storage/',
+        read_only       => 'no',
+        lock_file       => '/var/lock/container.lock';
+    'object':
+        uid             => 'swift',
+        gid             => 'swift',
+        max_connections => '10',
+        path            => '/srv/swift-storage/',
+        read_only       => 'no',
+        lock_file       => '/var/lock/object.lock',
+    }
+
+    # set up swift specific configs
+    File {
+        owner => 'swift',
+        group => 'swift',
+        mode  => '0440',
+    }
+
+    file { '/etc/swift/account-server.conf':
+        content => template('swift_new/account-server.conf.erb'),
+    }
+
+    file { '/etc/swift/container-server.conf':
+        content => template('swift_new/container-server.conf.erb'),
+    }
+
+    file { '/etc/swift/object-server.conf':
+        content => template('swift_new/object-server.conf.erb'),
+    }
+
+    file { '/srv/swift-storage':
+        ensure  => 'directory',
+        require => Package['swift'],
+        owner   => 'swift',
+        group   => 'swift',
+        # the 1 is to allow nagios to read the drives for check_disk
+        mode    => '0751',
+    }
+
+    service { [
+        'swift-account',
+        'swift-account-auditor',
+        'swift-account-reaper',
+        'swift-account-replicator',
+        'swift-container',
+        'swift-container-auditor',
+        'swift-container-replicator',
+        'swift-container-updater',
+        'swift-object',
+        'swift-object-auditor',
+        'swift-object-replicator',
+        'swift-object-updater',
+    ]:
+        ensure => 'running',
+    }
+
+
+    # install swift-drive-audit as a cronjob;
+    # it checks the disks every 60 minutes
+    # and unmounts failed disks. It logs its actions to /var/log/syslog.
+
+    # this file comes from the python-swift package
+    # but there are local improvements
+    # that are not yet merged upstream.
+    file { '/usr/bin/swift-drive-audit':
+        owner  => 'root',
+        group  => 'root',
+        mode   => '0755',
+        source => 'puppet:///modules/swift_new/swift-drive-audit',
+    }
+    file { '/etc/swift/swift-drive-audit.conf':
+        owner  => 'root',
+        group  => 'root',
+        mode   => '0440',
+        source => 'puppet:///modules/swift_new/swift-drive-audit.conf',
+    }
+    cron { 'swift-drive-audit':
+        ensure  => 'present',
+        command => '/usr/bin/swift-drive-audit 
/etc/swift/swift-drive-audit.conf',
+        user    => 'root',
+        minute  => '1',
+        require => [File['/usr/bin/swift-drive-audit'],
+                    File['/etc/swift/swift-drive-audit.conf']],
+    }
+}
diff --git a/modules/swift_new/manifests/storage/monitoring.pp 
b/modules/swift_new/manifests/storage/monitoring.pp
new file mode 100644
index 0000000..4009f55
--- /dev/null
+++ b/modules/swift_new/manifests/storage/monitoring.pp
@@ -0,0 +1,33 @@
+class swift_new::storage::monitoring {
+    define monitor_swift_daemon {
+        # nrpe::monitor_service will create
+        # nrpe::check command definition and a
+        # monitor_service definition which exports to nagios
+        nrpe::monitor_service { $title:
+            description  => $title,
+            nrpe_command => "/usr/lib/nagios/plugins/check_procs -c 1: 
--ereg-argument-array='^/usr/bin/python /usr/bin/${title}'",
+        }
+    }
+    include nrpe
+
+    # RT-2593. Moved here from nrpe_local.cfg
+    monitor_swift_daemon { [
+        'swift-account-auditor',
+        'swift-account-reaper',
+        'swift-account-replicator',
+        'swift-account-server',
+        'swift-container-auditor',
+        'swift-container-replicator',
+        'swift-container-server',
+        'swift-container-updater',
+        'swift-object-auditor',
+        'swift-object-replicator',
+        'swift-object-server',
+        'swift-object-updater',
+    ]: }
+
+    nrpe::monitor_service { 'load_average':
+        description  => 'very high load average likely xfs',
+        nrpe_command => '/usr/lib/nagios/plugins/check_load -w 80,80,80 -c 
200,100,100',
+    }
+}
diff --git a/modules/swift_new/templates/account-server.conf.erb 
b/modules/swift_new/templates/account-server.conf.erb
new file mode 100644
index 0000000..c2a31e3
--- /dev/null
+++ b/modules/swift_new/templates/account-server.conf.erb
@@ -0,0 +1,28 @@
+[DEFAULT]
+bind_ip = 0.0.0.0
+devices = /srv/swift-storage/
+workers = <%= @processorcount %>
+db_preallocation = on
+# statsd collection is off for the initial deploy; on after figuring out 
ganglia issues
+# log_statsd_host = localhost
+# log_statsd_port = 8125
+# log_statsd_default_sample_rate = 1
+# log_statsd_metric_prefix =
+
+[pipeline:main]
+pipeline = recon account-server
+
+[filter:recon]
+use = egg:swift#recon
+recon_cache_path = /var/cache/swift
+
+[app:account-server]
+use = egg:swift#account
+
+[account-replicator]
+concurrency = 1
+
+[account-auditor]
+concurrency = 1
+
+[account-reaper]
diff --git a/modules/swift_new/templates/container-server.conf.erb 
b/modules/swift_new/templates/container-server.conf.erb
new file mode 100644
index 0000000..cd00257
--- /dev/null
+++ b/modules/swift_new/templates/container-server.conf.erb
@@ -0,0 +1,31 @@
+[DEFAULT]
+bind_ip = 0.0.0.0
+devices = /srv/swift-storage/
+workers = <%= @processorcount %>
+db_preallocation = on
+# statsd collection is off for the initial deploy; on after figuring out 
ganglia issues
+# log_statsd_host = localhost
+# log_statsd_port = 8125
+# log_statsd_default_sample_rate = 1
+# log_statsd_metric_prefix =
+
+
+[pipeline:main]
+pipeline = recon container-server
+
+[filter:recon]
+use = egg:swift#recon
+recon_cache_path = /var/cache/swift
+
+[app:container-server]
+use = egg:swift#container
+
+[container-replicator]
+concurrency = 1
+
+[container-updater]
+concurrency = 1
+
+[container-auditor]
+
+[container-sync]
diff --git a/modules/swift_new/templates/dispersion.conf.erb 
b/modules/swift_new/templates/dispersion.conf.erb
new file mode 100644
index 0000000..eedfc6e
--- /dev/null
+++ b/modules/swift_new/templates/dispersion.conf.erb
@@ -0,0 +1,7 @@
+# This file is managed by Puppet!
+
+[dispersion]
+auth_url = <%= @dispersion_account['auth'] %>
+auth_user = <%= @dispersion_account['user'] %>
+auth_key = <%= @dispersion_account['key'] %>
+swift_dir = '/etc/swift'
diff --git a/modules/swift_new/templates/object-server.conf.erb 
b/modules/swift_new/templates/object-server.conf.erb
new file mode 100644
index 0000000..232c029
--- /dev/null
+++ b/modules/swift_new/templates/object-server.conf.erb
@@ -0,0 +1,35 @@
+[DEFAULT]
+bind_ip = 0.0.0.0
+devices = /srv/swift-storage/
+workers = 100
+# statsd collection is off for the initial deploy; on after figuring out 
ganglia issues
+# log_statsd_host = localhost
+# log_statsd_port = 8125
+# log_statsd_default_sample_rate = 1
+# log_statsd_metric_prefix =
+
+
+[pipeline:main]
+pipeline = recon object-server
+
+[filter:recon]
+use = egg:swift#recon
+recon_cache_path = /var/cache/swift
+
+[app:object-server]
+use = egg:swift#object
+# 5G, ought to be enough for everybody
+keep_cache_size = 5368709120
+allowed_headers = content-disposition,
+       content-encoding,
+       x-delete-at,
+       x-object-manifest,
+       x-content-duration
+
+[object-replicator]
+concurrency = 3
+
+[object-updater]
+concurrency = 1
+
+[object-auditor]
diff --git a/modules/swift_new/templates/proxy-server.conf.erb 
b/modules/swift_new/templates/proxy-server.conf.erb
new file mode 100644
index 0000000..5d5dbfd
--- /dev/null
+++ b/modules/swift_new/templates/proxy-server.conf.erb
@@ -0,0 +1,67 @@
+# This file is managed by Puppet!
+
+[DEFAULT]
+bind_port = <%= @bind_port %>
+workers = <%= @num_workers %>
+user = swift
+<% if @statsd_host -%>
+log_statsd_host = <%= @statsd_host %>
+log_statsd_sample_rate_factor = <%= @statsd_sample_rate_factor %>
+<% if @statsd_metric_prefix -%>
+log_statsd_metric_prefix = <%= @statsd_metric_prefix %>
+<% end -%>
+<% end -%>
+
+[pipeline:main]
+pipeline = rewrite healthcheck cache tempurl tempauth cors proxy-logging 
proxy-server
+
+[app:proxy-server]
+use = egg:swift#proxy
+account_autocreate = true
+
+[filter:tempurl]
+use = egg:swift#tempurl
+# default includes PUT
+methods = GET HEAD
+
+[filter:tempauth]
+use = egg:swift#tempauth
+token_life = 604800
+<% @accounts.each_pair do |name, info| -%>
+<%= "user_#{info['user'].gsub(':', '_')} = #{info['key']} #{info['access']} 
#{info['auth']}" %>
+<% end -%>
+
+[filter:healthcheck]
+use = egg:swift#healthcheck
+
+[filter:cache]
+use = egg:swift#memcache
+memcache_servers = <%= @memcached_servers.join(",") %>
+memcache_serialization_support = 2
+# per worker!
+memcache_max_connections = 12
+
+[filter:cors]
+paste.filter_factory = wmf.cors:filter_factory
+
+[filter:proxy-logging]
+use = egg:swift#proxy_logging
+set access_log_facility = LOG_LOCAL1
+
+[filter:rewrite]
+# the auth system turns our login and key into an account / token pair.
+# the account remains valid forever, but the token times out.
+account = <%= @rewrite_account['account_name'] %>
+# the name of the scaler cluster.
+thumbhost = <%= @rewrite_thumb_server %>
+# upload doesn't like our User-agent (Python-urllib/2.6), otherwise we could 
call it using urllib2.urlopen()
+user_agent = Mozilla/5.0
+# this list is the containers that should be sharded
+shard_container_list = <%= @shard_container_list %>
+# backend_url_format controls whether we pass the URL through to the thumbhost 
unmolested
+# or mangle it to be consumed by mediawiki.  ms5 takes URLs unmolested, 
mediawiki wants them
+# transformed to something more palatable (specifically, turning 
http://upload/proj/lang/ into http://lang.proj/
+# valid options are 'asis' (leave it alone) and 'sitelang' (change upload to 
lang.site.org)
+backend_url_format = <%= @backend_url_format %>
+
+paste.filter_factory = wmf.rewrite:filter_factory
diff --git a/modules/swift_new/templates/swift.conf.erb 
b/modules/swift_new/templates/swift.conf.erb
new file mode 100644
index 0000000..355d369
--- /dev/null
+++ b/modules/swift_new/templates/swift.conf.erb
@@ -0,0 +1,3 @@
+[swift-hash]
+# random unique string that can never change (DO NOT LOSE)
+swift_hash_path_suffix = <%= @hash_path_suffix %>

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I265b586fb0e54cf1f0e5c1463813986f42b1dd12
Gerrit-PatchSet: 1
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Filippo Giunchedi <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to