Пример #1
0
 def __init__(self, conf, container_ring=None, object_ring=None):
     #: The dict of configuration values from the [container-sync] section
     #: of the container-server.conf.
     self.conf = conf
     #: Logger to use for container-sync log lines.
     self.logger = get_logger(conf, log_route='container-sync')
     #: Path to the local device mount points.
     self.devices = conf.get('devices', '/srv/node')
     #: Indicates whether mount points should be verified as actual mount
     #: points (normally true, false for tests and SAIO).
     self.mount_check = config_true_value(conf.get('mount_check', 'true'))
     #: Minimum time between full scans. This is to keep the daemon from
     #: running wild on near empty systems.
     self.interval = int(conf.get('interval', 300))
     #: Maximum amount of time to spend syncing a container before moving on
     #: to the next one. If a conatiner sync hasn't finished in this time,
     #: it'll just be resumed next scan.
     self.container_time = int(conf.get('container_time', 60))
     #: ContainerSyncCluster instance for validating sync-to values.
     self.realms_conf = ContainerSyncRealms(
         os.path.join(
             conf.get('swift_dir', '/etc/swift'),
             'container-sync-realms.conf'),
         self.logger)
     #: The list of hosts we're allowed to send syncs to. This can be
     #: overridden by data in self.realms_conf
     self.allowed_sync_hosts = [
         h.strip()
         for h in conf.get('allowed_sync_hosts', '127.0.0.1').split(',')
         if h.strip()]
     self.http_proxies = [
         a.strip()
         for a in conf.get('sync_proxy', '').split(',')
         if a.strip()]
     #: Number of containers with sync turned on that were successfully
     #: synced.
     self.container_syncs = 0
     #: Number of successful DELETEs triggered.
     self.container_deletes = 0
     #: Number of successful PUTs triggered.
     self.container_puts = 0
     #: Number of containers that didn't have sync turned on.
     self.container_skips = 0
     #: Number of containers that had a failure of some type.
     self.container_failures = 0
     #: Time of last stats report.
     self.reported = time()
     swift_dir = conf.get('swift_dir', '/etc/swift')
     #: swift.common.ring.Ring for locating containers.
     self.container_ring = container_ring or Ring(swift_dir,
                                                  ring_name='container')
     #: swift.common.ring.Ring for locating objects.
     self.object_ring = object_ring or Ring(swift_dir, ring_name='object')
     self._myips = whataremyips()
     self._myport = int(conf.get('bind_port', 6001))
     swift.common.db.DB_PREALLOCATION = \
         config_true_value(conf.get('db_preallocation', 'f'))
Пример #2
0
 def test_empty(self):
     fname = 'container-sync-realms.conf'
     fcontents = ''
     with temptree([fname], [fcontents]) as tempdir:
         logger = FakeLogger()
         fpath = os.path.join(tempdir, fname)
         csr = ContainerSyncRealms(fpath, logger)
         self.assertEqual(logger.all_log_lines(), {})
         self.assertEqual(csr.mtime_check_interval, 300)
         self.assertEqual(csr.realms(), [])
Пример #3
0
 def test_get_sig(self):
     fname = 'container-sync-realms.conf'
     fcontents = ''
     with temptree([fname], [fcontents]) as tempdir:
         logger = FakeLogger()
         fpath = os.path.join(tempdir, fname)
         csr = ContainerSyncRealms(fpath, logger)
         self.assertEqual(
             csr.get_sig('GET', '/some/path', '1387212345.67890',
                         'my_nonce', 'realm_key', 'user_key'),
             '5a6eb486eb7b44ae1b1f014187a94529c3f9c8f9')
 def test_no_file_there(self):
     unique = uuid.uuid4().hex
     logger = FakeLogger()
     csr = ContainerSyncRealms(unique, logger)
     self.assertEqual(
         logger.lines_dict,
         {'debug': [
             "Could not load '%s': [Errno 2] No such file or directory: "
             "'%s'" % (unique, unique)]})
     self.assertEqual(csr.mtime_check_interval, 300)
     self.assertEqual(csr.realms(), [])
Пример #5
0
 def __init__(self, conf, logger=None):
     super(ContainerController, self).__init__(conf)
     self.logger = logger or get_logger(conf, log_route='container-server')
     self.log_requests = config_true_value(conf.get('log_requests', 'true'))
     self.root = conf.get('devices', '/srv/node')
     self.mount_check = config_true_value(conf.get('mount_check', 'true'))
     self.node_timeout = float(conf.get('node_timeout', 3))
     self.conn_timeout = float(conf.get('conn_timeout', 0.5))
     #: ContainerSyncCluster instance for validating sync-to values.
     self.realms_conf = ContainerSyncRealms(
         os.path.join(conf.get('swift_dir', '/etc/swift'),
                      'container-sync-realms.conf'), self.logger)
     #: The list of hosts we're allowed to send syncs to. This can be
     #: overridden by data in self.realms_conf
     self.allowed_sync_hosts = [
         h.strip()
         for h in conf.get('allowed_sync_hosts', '127.0.0.1').split(',')
         if h.strip()
     ]
     self.replicator_rpc = ContainerReplicatorRpc(self.root,
                                                  DATADIR,
                                                  ContainerBroker,
                                                  self.mount_check,
                                                  logger=self.logger)
     if conf.get('auto_create_account_prefix'):
         self.logger.warning('Option auto_create_account_prefix is '
                             'deprecated. Configure '
                             'auto_create_account_prefix under the '
                             'swift-constraints section of '
                             'swift.conf. This option will '
                             'be ignored in a future release.')
         self.auto_create_account_prefix = \
             conf['auto_create_account_prefix']
     else:
         self.auto_create_account_prefix = AUTO_CREATE_ACCOUNT_PREFIX
     self.shards_account_prefix = (self.auto_create_account_prefix +
                                   'shards_')
     if config_true_value(conf.get('allow_versions', 'f')):
         self.save_headers.append('x-versions-location')
     if 'allow_versions' in conf:
         self.logger.warning('Option allow_versions is deprecated. '
                             'Configure the versioned_writes middleware in '
                             'the proxy-server instead. This option will '
                             'be ignored in a future release.')
     swift.common.db.DB_PREALLOCATION = \
         config_true_value(conf.get('db_preallocation', 'f'))
     swift.common.db.QUERY_LOGGING = \
         config_true_value(conf.get('db_query_logging', 'f'))
     self.sync_store = ContainerSyncStore(self.root, self.logger,
                                          self.mount_check)
     self.fallocate_reserve, self.fallocate_is_percent = \
         config_fallocate_value(conf.get('fallocate_reserve', '1%'))
 def test_error_parsing(self):
     fname = 'container-sync-realms.conf'
     fcontents = 'invalid'
     with temptree([fname], [fcontents]) as tempdir:
         logger = FakeLogger()
         fpath = os.path.join(tempdir, fname)
         csr = ContainerSyncRealms(fpath, logger)
         self.assertEqual(
             logger.lines_dict,
             {'error': [
                 "Could not load '%s': File contains no section headers.\n"
                 "file: %s, line: 1\n"
                 "'invalid'" % (fpath, fpath)]})
         self.assertEqual(csr.mtime_check_interval, 300)
         self.assertEqual(csr.realms(), [])
Пример #7
0
    def test_empty_realm(self):
        fname = 'container-sync-realms.conf'
        fcontents = '''
[US]
'''
        with temptree([fname], [fcontents]) as tempdir:
            logger = FakeLogger()
            fpath = os.path.join(tempdir, fname)
            csr = ContainerSyncRealms(fpath, logger)
            self.assertEqual(logger.all_log_lines(), {})
            self.assertEqual(csr.mtime_check_interval, 300)
            self.assertEqual(csr.realms(), ['US'])
            self.assertIsNone(csr.key('US'))
            self.assertIsNone(csr.key2('US'))
            self.assertEqual(csr.clusters('US'), [])
            self.assertIsNone(csr.endpoint('US', 'JUST_TESTING'))
    def test_bad_mtime_check_interval(self):
        fname = 'container-sync-realms.conf'
        fcontents = '''
[DEFAULT]
mtime_check_interval = invalid
'''
        with temptree([fname], [fcontents]) as tempdir:
            logger = FakeLogger()
            fpath = os.path.join(tempdir, fname)
            csr = ContainerSyncRealms(fpath, logger)
            self.assertEqual(
                logger.lines_dict,
                {'error': [
                    "Error in '%s' with mtime_check_interval: invalid literal "
                    "for int() with base 10: 'invalid'" % fpath]})
            self.assertEqual(csr.mtime_check_interval, 300)
 def test_os_error(self):
     fname = 'container-sync-realms.conf'
     fcontents = ''
     with temptree([fname], [fcontents]) as tempdir:
         logger = FakeLogger()
         fpath = os.path.join(tempdir, fname)
         os.chmod(tempdir, 0)
         csr = ContainerSyncRealms(fpath, logger)
         try:
             self.assertEqual(
                 logger.lines_dict,
                 {'error': [
                     "Could not load '%s': [Errno 13] Permission denied: "
                     "'%s'" % (fpath, fpath)]})
             self.assertEqual(csr.mtime_check_interval, 300)
             self.assertEqual(csr.realms(), [])
         finally:
             os.chmod(tempdir, 0700)
Пример #10
0
    def test_bad_mtime_check_interval(self):
        fname = 'container-sync-realms.conf'
        fcontents = '''
[DEFAULT]
mtime_check_interval = invalid
'''
        with temptree([fname], [fcontents]) as tempdir:
            logger = debug_logger()
            fpath = os.path.join(tempdir, fname)
            csr = ContainerSyncRealms(fpath, logger)
            logs = logger.all_log_lines()
            self.assertEqual(logs, {'error': [ANY]})
            line = logs['error'][0]
            self.assertIn(
                "Error in '%s' with mtime_check_interval: "
                "could not convert string to float:" % fpath, line)

            self.assertEqual(csr.mtime_check_interval, 300)
Пример #11
0
    def test_one_realm(self):
        fname = 'container-sync-realms.conf'
        fcontents = '''
[US]
key = 9ff3b71c849749dbaec4ccdd3cbab62b
cluster_dfw1 = http://dfw1.host/v1/
'''
        with temptree([fname], [fcontents]) as tempdir:
            logger = FakeLogger()
            fpath = os.path.join(tempdir, fname)
            csr = ContainerSyncRealms(fpath, logger)
            self.assertEqual(logger.all_log_lines(), {})
            self.assertEqual(csr.mtime_check_interval, 300)
            self.assertEqual(csr.realms(), ['US'])
            self.assertEqual(csr.key('US'), '9ff3b71c849749dbaec4ccdd3cbab62b')
            self.assertIsNone(csr.key2('US'))
            self.assertEqual(csr.clusters('US'), ['DFW1'])
            self.assertEqual(csr.endpoint('US', 'DFW1'),
                             'http://dfw1.host/v1/')
Пример #12
0
 def __init__(self, app, conf, logger=None):
     self.app = app
     self.conf = conf
     self.logger = logger or get_logger(conf, log_route='container_sync')
     self.realms_conf = ContainerSyncRealms(
         os.path.join(conf.get('swift_dir', '/etc/swift'),
                      'container-sync-realms.conf'), self.logger)
     self.allow_full_urls = config_true_value(
         conf.get('allow_full_urls', 'true'))
     # configure current realm/cluster for /info
     self.realm = self.cluster = None
     current = conf.get('current', None)
     if current:
         try:
             self.realm, self.cluster = (
                 p.upper() for p in current.strip('/').split('/'))
         except ValueError:
             self.logger.error('Invalid current //REALM/CLUSTER (%s)',
                               current)
     self.register_info()
 def test_error_parsing(self):
     fname = 'container-sync-realms.conf'
     fcontents = 'invalid'
     with temptree([fname], [fcontents]) as tempdir:
         logger = debug_logger()
         fpath = os.path.join(tempdir, fname)
         csr = ContainerSyncRealms(fpath, logger)
         if six.PY2:
             fmt = "Could not load '%s': " \
                 "File contains no section headers.\n" \
                 "file: %s, line: 1\n" \
                 "'invalid'"
         else:
             fmt = "Could not load '%s': " \
                 "File contains no section headers.\n" \
                 "file: '%s', line: 1\n" \
                 "'invalid'"
         self.assertEqual(logger.all_log_lines(),
                          {'error': [fmt % (fpath, fpath)]})
         self.assertEqual(csr.mtime_check_interval, 300)
         self.assertEqual(csr.realms(), [])
Пример #14
0
    def test_os_error(self):
        fname = 'container-sync-realms.conf'
        fcontents = ''
        with temptree([fname], [fcontents]) as tempdir:
            logger = FakeLogger()
            fpath = os.path.join(tempdir, fname)

            def _mock_getmtime(path):
                raise OSError(errno.EACCES,
                              os.strerror(errno.EACCES) +
                              ": '%s'" % (fpath))
            with patch('os.path.getmtime', _mock_getmtime):
                csr = ContainerSyncRealms(fpath, logger)

            self.assertEqual(
                logger.all_log_lines(),
                {'error': [
                    "Could not load '%s': [Errno 13] Permission denied: "
                    "'%s'" % (fpath, fpath)]})
            self.assertEqual(csr.mtime_check_interval, 300)
            self.assertEqual(csr.realms(), [])
Пример #15
0
    def __init__(self, conf, container_ring=None, logger=None):
        #: The dict of configuration values from the [container-sync] section
        #: of the container-server.conf.
        self.conf = conf
        #: Logger to use for container-sync log lines.
        self.logger = logger or get_logger(conf, log_route='container-sync')
        #: Path to the local device mount points.
        self.devices = conf.get('devices', '/srv/node')
        #: Indicates whether mount points should be verified as actual mount
        #: points (normally true, false for tests and SAIO).
        self.mount_check = config_true_value(conf.get('mount_check', 'true'))
        #: Minimum time between full scans. This is to keep the daemon from
        #: running wild on near empty systems.
        self.interval = int(conf.get('interval', 300))
        #: Maximum amount of time to spend syncing a container before moving on
        #: to the next one. If a container sync hasn't finished in this time,
        #: it'll just be resumed next scan.
        self.container_time = int(conf.get('container_time', 60))
        #: ContainerSyncCluster instance for validating sync-to values.
        self.realms_conf = ContainerSyncRealms(
            os.path.join(conf.get('swift_dir', '/etc/swift'),
                         'container-sync-realms.conf'), self.logger)
        #: The list of hosts we're allowed to send syncs to. This can be
        #: overridden by data in self.realms_conf
        self.allowed_sync_hosts = [
            h.strip()
            for h in conf.get('allowed_sync_hosts', '127.0.0.1').split(',')
            if h.strip()
        ]
        self.http_proxies = [
            a.strip() for a in conf.get('sync_proxy', '').split(',')
            if a.strip()
        ]
        #: ContainerSyncStore instance for iterating over synced containers
        self.sync_store = ContainerSyncStore(self.devices, self.logger,
                                             self.mount_check)
        #: Number of containers with sync turned on that were successfully
        #: synced.
        self.container_syncs = 0
        #: Number of successful DELETEs triggered.
        self.container_deletes = 0
        #: Number of successful PUTs triggered.
        self.container_puts = 0
        #: Number of containers whose sync has been turned off, but
        #: are not yet cleared from the sync store.
        self.container_skips = 0
        #: Number of containers that had a failure of some type.
        self.container_failures = 0

        #: Per container stats. These are collected per container.
        #: puts - the number of puts that were done for the container
        #: deletes - the number of deletes that were fot the container
        #: bytes - the total number of bytes transferred per the container
        self.container_stats = collections.defaultdict(int)
        self.container_stats.clear()

        #: Time of last stats report.
        self.reported = time()
        self.swift_dir = conf.get('swift_dir', '/etc/swift')
        #: swift.common.ring.Ring for locating containers.
        self.container_ring = container_ring or Ring(self.swift_dir,
                                                     ring_name='container')
        bind_ip = conf.get('bind_ip', '0.0.0.0')
        self._myips = whataremyips(bind_ip)
        self._myport = int(conf.get('bind_port', 6201))
        swift.common.db.DB_PREALLOCATION = \
            config_true_value(conf.get('db_preallocation', 'f'))
        self.conn_timeout = float(conf.get('conn_timeout', 5))
        request_tries = int(conf.get('request_tries') or 3)

        internal_client_conf_path = conf.get('internal_client_conf_path')
        if not internal_client_conf_path:
            self.logger.warning(
                _('Configuration option internal_client_conf_path not '
                  'defined. Using default configuration, See '
                  'internal-client.conf-sample for options'))
            internal_client_conf = ConfigString(ic_conf_body)
        else:
            internal_client_conf = internal_client_conf_path
        try:
            self.swift = InternalClient(internal_client_conf,
                                        'Swift Container Sync', request_tries)
        except (OSError, IOError) as err:
            if err.errno != errno.ENOENT and \
                    not str(err).endswith(' not found'):
                raise
            raise SystemExit(
                _('Unable to load internal client from config: '
                  '%(conf)r (%(error)s)') % {
                      'conf': internal_client_conf_path,
                      'error': err
                  })