Skip to content

Instantly share code, notes, and snippets.

@clayg
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clayg/0db807e42d9b1289118e to your computer and use it in GitHub Desktop.
Save clayg/0db807e42d9b1289118e to your computer and use it in GitHub Desktop.
backups/
example.conf.d/

Here's an example how we might generalize file reloading.

gist won't let me upload the example.conf.d as a directory

[swift-hash]
# swift_hash_path_suffix and swift_hash_path_prefix are used as part of the
# the hashing algorithm when determining data placement in the cluster.
# These values should remain secret and MUST NOT change
# once a cluster has been deployed.
swift_hash_path_suffix = changeme
swift_hash_path_prefix = changeme
# storage policies are defined here and determine various characteristics
# about how objects are stored and treated. Policies are specified by name on
# a per container basis. Names are case-insensitive. The policy index is
# specified in the section header and is used internally. The policy with
# index 0 is always used for legacy containers and can be given a name for use
# in metadata however the ring file name will always be 'object.ring.gz' for
# backwards compatibility. If no policies are defined a policy with index 0
# will be automatically created for backwards compatibility and given the name
# Policy-0. A default policy is used when creating new containers when no
# policy is specified in the request. If no other policies are defined the
# policy with index 0 will be declared the default. If multiple policies are
# defined you must define a policy with index 0 and you must specify a
# default. It is recommended you always define a section for
# storage-policy:0.
[storage-policy:0]
name = Policy-0
default = yes
# the following section would declare a policy called 'silver', the number of
# replicas will be determined by how the ring is built. In this example the
# 'silver' policy could have a lower or higher # of replicas than the
# 'Policy-0' policy above. The ring filename will be 'object-1.ring.gz'. You
# may only specify one storage policy section as the default. If you changed
# this section to specify 'silver' as the default, when a client created a new
# container w/o a policy specified, it will get the 'silver' policy because
# this config has specified it as the default. However if a legacy container
# (one created with a pre-policy version of swift) is accessed, it is known
# implicitly to be assigned to the policy with index 0 as opposed to the
# current default.
#[storage-policy:1]
#name = silver
# The swift-constraints section sets the basic constraints on data
# saved in the swift cluster. These constraints are automatically
# published by the proxy server in responses to /info requests.
[swift-constraints]
# max_file_size is the largest "normal" object that can be saved in
# the cluster. This is also the limit on the size of each segment of
# a "large" object when using the large object manifest support.
# This value is set in bytes. Setting it to lower than 1MiB will cause
# some tests to fail. It is STRONGLY recommended to leave this value at
# the default (5 * 2**30 + 2).
#max_file_size = 5368709122
# max_meta_name_length is the max number of bytes in the utf8 encoding
# of the name portion of a metadata header.
#max_meta_name_length = 128
# max_meta_value_length is the max number of bytes in the utf8 encoding
# of a metadata value
#max_meta_value_length = 256
# max_meta_count is the max number of metadata keys that can be stored
# on a single account, container, or object
#max_meta_count = 90
# max_meta_overall_size is the max number of bytes in the utf8 encoding
# of the metadata (keys + values)
#max_meta_overall_size = 4096
# max_header_size is the max number of bytes in the utf8 encoding of each
# header. Using 8192 as default because eventlet use 8192 as max size of
# header line. This value may need to be increased when using identity
# v3 API tokens including more than 7 catalog entries.
# See also include_service_catalog in proxy-server.conf-sample
# (documented in overview_auth.rst)
#max_header_size = 8192
# max_object_name_length is the max number of bytes in the utf8 encoding
# of an object name
#max_object_name_length = 1024
# container_listing_limit is the default (and max) number of items
# returned for a container listing request
#container_listing_limit = 10000
# account_listing_limit is the default (and max) number of items returned
# for an account listing request
#account_listing_limit = 10000
# max_account_name_length is the max number of bytes in the utf8 encoding
# of an account name
#max_account_name_length = 256
# max_container_name_length is the max number of bytes in the utf8 encoding
# of a container name
#max_container_name_length = 256
{"foo": "bar"}
€}qU138qU 9615a53212565d6b5d1835937c156b25qs.
#!/usr/bin/env python
import os
import time
class ReloadingFile(object):
def __init__(self, filename, reload_time=300):
self.filename = filename
self.reload_time = reload_time
self._cached_data = None
self._last_reload = 0
self._last_mtime = 0
self.data = None
def _get_mtime(self):
return os.stat(self.filename).st_mtime
def has_changed(self):
mtime = self._get_mtime()
if mtime == self._last_mtime:
return False
self._last_mtime = mtime
return True
def reload(self):
with open(self.filename) as f:
return self.parse(f)
def parse(self, f):
return f.read()
def get_data(self):
now = time.time()
if self._last_reload + self.reload_time < now:
self._last_reload = now
# skip reload if mtimes are the same
if self.has_changed():
self._cached_data = self.reload()
return self._cached_data
import json
class ReloadingJson(ReloadingFile):
def parse(self, f):
return json.load(f)
from swift.common.utils import readconf
class ReloadingConfigFile(ReloadingFile):
def __init__(self, *args, **kwargs):
self._section_name = kwargs.pop('section_name', None)
super(ReloadingConfigFile, self).__init__(*args, **kwargs)
def reload(self):
return readconf(self.filename, section_name=self._section_name)
class ReloadingConf(ReloadingConfigFile):
def _get_mtime(self):
mtime = 0
for path, dirs, names in os.walk(self.filename):
for name in names:
filename = os.path.join(path, name)
mtime = max((mtime, os.stat(filename).st_mtime))
return mtime
import pickle
class ReloadingPickle(ReloadingFile):
def parse(self, f):
return pickle.load(f)
from swift.common.ring import RingData
class ReloadingRing(ReloadingFile):
def reload(self):
return RingData.load(self.filename)
# command line mode is for testing, not really part of the example
import sys
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('path', help='path to reloading file')
parser.add_argument('-v', '--verbose', action='store_true', help='more info')
def main():
args = parser.parse_args()
path = args.path
if os.path.isdir(path):
class_ = ReloadingConf
elif path.endswith('json'):
class_ = ReloadingJson
elif path.endswith('conf'):
class_ = ReloadingConfigFile
elif path.endswith('.pkl'):
class_ = ReloadingPickle
elif path.endswith('.ring.gz'):
class_ = ReloadingRing
else:
class_ = ReloadingFile
conf = class_(path, reload_time=10)
while True:
data = conf.get_data()
print '%s (%s)' % (id(data), conf._last_reload)
if args.verbose:
print data
time.sleep(3)
if __name__ == "__main__":
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment