コード例 #1
0
ファイル: builder.py プロジェクト: zhoubing00/swift
 def get_ring(self):
     """
     Get the ring, or more specifically, the swift.common.ring.RingData.
     This ring data is the minimum required for use of the ring. The ring
     builder itself keeps additional data such as when partitions were last
     moved.
     """
     # We cache the self._ring value so multiple requests for it don't build
     # it multiple times. Be sure to set self._ring = None whenever the ring
     # will need to be rebuilt.
     if not self._ring:
         # Make devs list (with holes for deleted devices) and not including
         # builder-specific extra attributes.
         devs = [None] * len(self.devs)
         for dev in self._iter_devs():
             devs[dev['id']] = dict((k, v) for k, v in dev.items()
                                    if k not in ('parts', 'parts_wanted'))
         # Copy over the replica+partition->device assignments, the device
         # information, and the part_shift value (the number of bits to
         # shift an unsigned int >I right to obtain the partition for the
         # int).
         if not self._replica2part2dev:
             self._ring = RingData([], devs, 32 - self.part_power)
         else:
             self._ring = \
                 RingData([array('H', p2d) for p2d in
                           self._replica2part2dev],
                          devs, 32 - self.part_power)
     return self._ring
コード例 #2
0
ファイル: composite_builder.py プロジェクト: pikalulu/swift-1
def _make_composite_ring(builders):
    """
    Given a list of component ring builders, return a composite RingData
    instance.

    :param builders: a list of
        :class:`swift.common.ring.builder.RingBuilder` instances
    :return: a new RingData instance built from the component builders
    :raises ValueError: if the builders are invalid with respect to each other
    """
    composite_r2p2d = []
    composite_devs = []
    device_offset = 0
    for builder in builders:
        # copy all devs list and replica2part2dev table to be able
        # to modify the id for each dev
        devs = copy.deepcopy(builder.devs)
        r2p2d = copy.deepcopy(builder._replica2part2dev)
        for part2dev in r2p2d:
            for part, dev in enumerate(part2dev):
                part2dev[part] += device_offset
        for dev in [d for d in devs if d]:
            # note that some devs may not be referenced in r2p2d but update
            # their dev id nonetheless
            dev['id'] += device_offset
        composite_r2p2d.extend(r2p2d)
        composite_devs.extend(devs)
        device_offset += len(builder.devs)

    return RingData(composite_r2p2d, composite_devs, builders[0].part_shift)
コード例 #3
0
def write_fake_ring(path, *devs):
    """
    Pretty much just a two node, two replica, 2 part power ring...
    """
    dev1 = {
        'id': 0,
        'zone': 0,
        'device': 'sda1',
        'ip': '127.0.0.1',
        'port': 6200
    }
    dev2 = {
        'id': 1,
        'zone': 0,
        'device': 'sdb1',
        'ip': '127.0.0.1',
        'port': 6200
    }

    dev1_updates, dev2_updates = devs or ({}, {})

    dev1.update(dev1_updates)
    dev2.update(dev2_updates)

    replica2part2dev_id = [[0, 1, 0, 1], [1, 0, 1, 0]]
    devs = [dev1, dev2]
    part_shift = 30
    with closing(GzipFile(path, 'wb')) as f:
        pickle.dump(RingData(replica2part2dev_id, devs, part_shift), f)
コード例 #4
0
ファイル: test_updater.py プロジェクト: wanghaijunye/swift
 def setUp(self):
     utils.HASH_PATH_SUFFIX = 'endcap'
     utils.HASH_PATH_PREFIX = 'startcap'
     self.testdir = os.path.join(mkdtemp(), 'tmp_test_container_updater')
     rmtree(self.testdir, ignore_errors=1)
     os.mkdir(self.testdir)
     ring_file = os.path.join(self.testdir, 'account.ring.gz')
     with closing(GzipFile(ring_file, 'wb')) as f:
         pickle.dump(
             RingData([[0, 1, 0, 1], [1, 0, 1, 0]], [{
                 'id': 0,
                 'ip': '127.0.0.1',
                 'port': 12345,
                 'device': 'sda1',
                 'zone': 0
             }, {
                 'id': 1,
                 'ip': '127.0.0.1',
                 'port': 12345,
                 'device': 'sda1',
                 'zone': 2
             }], 30), f)
     self.devices_dir = os.path.join(self.testdir, 'devices')
     os.mkdir(self.devices_dir)
     self.sda1 = os.path.join(self.devices_dir, 'sda1')
     os.mkdir(self.sda1)
コード例 #5
0
 def setUp(self):
     utils.HASH_PATH_SUFFIX = 'endcap'
     utils.HASH_PATH_PREFIX = ''
     self.testdir = mkdtemp()
     ring_file = os.path.join(self.testdir, 'container.ring.gz')
     with closing(GzipFile(ring_file, 'wb')) as f:
         pickle.dump(
             RingData([[0, 1, 2, 0, 1, 2], [1, 2, 0, 1, 2, 0],
                       [2, 3, 1, 2, 3, 1]], [{
                           'id': 0,
                           'ip': '127.0.0.1',
                           'port': 1,
                           'device': 'sda1',
                           'zone': 0
                       }, {
                           'id': 1,
                           'ip': '127.0.0.1',
                           'port': 1,
                           'device': 'sda1',
                           'zone': 2
                       }, {
                           'id': 2,
                           'ip': '127.0.0.1',
                           'port': 1,
                           'device': 'sda1',
                           'zone': 4
                       }], 30), f)
     self.devices_dir = os.path.join(self.testdir, 'devices')
     os.mkdir(self.devices_dir)
     self.sda1 = os.path.join(self.devices_dir, 'sda1')
     os.mkdir(self.sda1)
     for policy in POLICIES:
         os.mkdir(os.path.join(self.sda1, get_tmp_dir(policy)))
     self.logger = debug_logger()
コード例 #6
0
 def setUp(self):
     utils.HASH_PATH_SUFFIX = 'endcap'
     self.testdir = os.path.join(os.path.dirname(__file__),
                                 'object_updater')
     rmtree(self.testdir, ignore_errors=1)
     os.mkdir(self.testdir)
     pickle.dump(
         RingData([[0, 1, 0, 1], [1, 0, 1, 0]], [{
             'id': 0,
             'ip': '127.0.0.1',
             'port': 1,
             'device': 'sda1',
             'zone': 0
         }, {
             'id': 1,
             'ip': '127.0.0.1',
             'port': 1,
             'device': 'sda1',
             'zone': 2
         }], 30),
         GzipFile(os.path.join(self.testdir, 'container.ring.gz'), 'wb'))
     self.devices_dir = os.path.join(self.testdir, 'devices')
     os.mkdir(self.devices_dir)
     self.sda1 = os.path.join(self.devices_dir, 'sda1')
     os.mkdir(self.sda1)
     os.mkdir(os.path.join(self.sda1, 'tmp'))
コード例 #7
0
 def get_ring(self):
     """
     Get the ring, or more specifically, the swift.common.ring.RingData.
     This ring data is the minimum required for use of the ring. The ring
     builder itself keeps additional data such as when partitions were last
     moved.
     """
     if not self._ring:
         devs = [None] * len(self.devs)
         for dev in self.devs:
             if dev is None:
                 continue
             devs[dev['id']] = dict((k, v) for k, v in dev.items()
                                    if k not in ('parts', 'parts_wanted'))
         if not self._replica2part2dev:
             self._ring = RingData([], devs, 32 - self.part_power)
         else:
             self._ring = \
             RingData([array('H', p2d) for p2d in self._replica2part2dev],
                      devs, 32 - self.part_power)
     return self._ring
コード例 #8
0
ファイル: helpers.py プロジェクト: gyaozhou/swift-read
def setup_servers(the_object_server=object_server, extra_conf=None):
    """
    Setup proxy, account, container and object servers using a set of fake
    rings and policies.

    :param the_object_server: The object server module to use (optional,
                              defaults to swift.obj.server)
    :param extra_conf: A dict of config options that will update the basic
                       config passed to all server instances.
    :returns: A dict containing the following entries:
                  orig_POLICIES: the value of storage_policy.POLICIES prior to
                                 it being patched with fake policies
                  orig_SysLogHandler: the value of utils.SysLogHandler prior to
                                      it being patched
                  testdir: root directory used for test files
                  test_POLICIES: a StoragePolicyCollection of fake policies
                  test_servers: a tuple of test server instances
                  test_sockets: a tuple of sockets used by test servers
                  test_coros: a tuple of greenthreads in which test servers are
                              running
    """
    context = {
        "orig_POLICIES": storage_policy._POLICIES,
        "orig_SysLogHandler": utils.SysLogHandler}

    utils.HASH_PATH_SUFFIX = b'endcap'
    utils.SysLogHandler = mock.MagicMock()
    # Since we're starting up a lot here, we're going to test more than
    # just chunked puts; we're also going to test parts of
    # proxy_server.Application we couldn't get to easily otherwise.
    context["testdir"] = _testdir = \
        os.path.join(mkdtemp(), 'tmp_test_proxy_server_chunked')
    mkdirs(_testdir)
    rmtree(_testdir)
    for drive in ('sda1', 'sdb1', 'sdc1', 'sdd1', 'sde1',
                  'sdf1', 'sdg1', 'sdh1', 'sdi1', 'sdj1',
                  'sdk1', 'sdl1'):
        mkdirs(os.path.join(_testdir, drive, 'tmp'))
    conf = {'devices': _testdir, 'swift_dir': _testdir,
            'mount_check': 'false', 'allowed_headers':
            'content-encoding, x-object-manifest, content-disposition, foo',
            'allow_versions': 't'}
    if extra_conf:
        conf.update(extra_conf)
    prolis = listen_zero()
    acc1lis = listen_zero()
    acc2lis = listen_zero()
    con1lis = listen_zero()
    con2lis = listen_zero()
    obj1lis = listen_zero()
    obj2lis = listen_zero()
    obj3lis = listen_zero()
    obj4lis = listen_zero()
    obj5lis = listen_zero()
    obj6lis = listen_zero()
    objsocks = [obj1lis, obj2lis, obj3lis, obj4lis, obj5lis, obj6lis]
    context["test_sockets"] = \
        (prolis, acc1lis, acc2lis, con1lis, con2lis, obj1lis, obj2lis, obj3lis,
         obj4lis, obj5lis, obj6lis)
    account_ring_path = os.path.join(_testdir, 'account.ring.gz')
    account_devs = [
        {'port': acc1lis.getsockname()[1]},
        {'port': acc2lis.getsockname()[1]},
    ]
    write_fake_ring(account_ring_path, *account_devs)
    container_ring_path = os.path.join(_testdir, 'container.ring.gz')
    container_devs = [
        {'port': con1lis.getsockname()[1]},
        {'port': con2lis.getsockname()[1]},
    ]
    write_fake_ring(container_ring_path, *container_devs)
    storage_policy._POLICIES = storage_policy.StoragePolicyCollection([
        StoragePolicy(0, 'zero', True),
        StoragePolicy(1, 'one', False),
        StoragePolicy(2, 'two', False),
        ECStoragePolicy(3, 'ec', ec_type=DEFAULT_TEST_EC_TYPE,
                        ec_ndata=2, ec_nparity=1, ec_segment_size=4096),
        ECStoragePolicy(4, 'ec-dup', ec_type=DEFAULT_TEST_EC_TYPE,
                        ec_ndata=2, ec_nparity=1, ec_segment_size=4096,
                        ec_duplication_factor=2)])
    obj_rings = {
        0: ('sda1', 'sdb1'),
        1: ('sdc1', 'sdd1'),
        2: ('sde1', 'sdf1'),
        # sdg1, sdh1, sdi1 taken by policy 3 (see below)
    }
    for policy_index, devices in obj_rings.items():
        policy = storage_policy.POLICIES[policy_index]
        obj_ring_path = os.path.join(_testdir, policy.ring_name + '.ring.gz')
        obj_devs = [
            {'port': objsock.getsockname()[1], 'device': dev}
            for objsock, dev in zip(objsocks, devices)]
        write_fake_ring(obj_ring_path, *obj_devs)

    # write_fake_ring can't handle a 3-element ring, and the EC policy needs
    # at least 6 devs to work with (ec_k=2, ec_m=1, duplication_factor=2),
    # so we do it manually
    devs = [{'id': 0, 'zone': 0, 'device': 'sdg1', 'ip': '127.0.0.1',
             'port': obj1lis.getsockname()[1]},
            {'id': 1, 'zone': 0, 'device': 'sdh1', 'ip': '127.0.0.1',
             'port': obj2lis.getsockname()[1]},
            {'id': 2, 'zone': 0, 'device': 'sdi1', 'ip': '127.0.0.1',
             'port': obj3lis.getsockname()[1]},
            {'id': 3, 'zone': 0, 'device': 'sdj1', 'ip': '127.0.0.1',
             'port': obj4lis.getsockname()[1]},
            {'id': 4, 'zone': 0, 'device': 'sdk1', 'ip': '127.0.0.1',
             'port': obj5lis.getsockname()[1]},
            {'id': 5, 'zone': 0, 'device': 'sdl1', 'ip': '127.0.0.1',
             'port': obj6lis.getsockname()[1]}]
    pol3_replica2part2dev_id = [[0, 1, 2, 0],
                                [1, 2, 0, 1],
                                [2, 0, 1, 2]]
    pol4_replica2part2dev_id = [[0, 1, 2, 3],
                                [1, 2, 3, 4],
                                [2, 3, 4, 5],
                                [3, 4, 5, 0],
                                [4, 5, 0, 1],
                                [5, 0, 1, 2]]
    obj3_ring_path = os.path.join(
        _testdir, storage_policy.POLICIES[3].ring_name + '.ring.gz')
    part_shift = 30
    with closing(GzipFile(obj3_ring_path, 'wb')) as fh:
        pickle.dump(RingData(pol3_replica2part2dev_id, devs, part_shift), fh)

    obj4_ring_path = os.path.join(
        _testdir, storage_policy.POLICIES[4].ring_name + '.ring.gz')
    part_shift = 30
    with closing(GzipFile(obj4_ring_path, 'wb')) as fh:
        pickle.dump(RingData(pol4_replica2part2dev_id, devs, part_shift), fh)

    prosrv = proxy_server.Application(conf, logger=debug_logger('proxy'))
    for policy in storage_policy.POLICIES:
        # make sure all the rings are loaded
        prosrv.get_object_ring(policy.idx)
    # don't lose this one!
    context["test_POLICIES"] = storage_policy._POLICIES
    acc1srv = account_server.AccountController(
        conf, logger=debug_logger('acct1'))
    acc2srv = account_server.AccountController(
        conf, logger=debug_logger('acct2'))
    con1srv = container_server.ContainerController(
        conf, logger=debug_logger('cont1'))
    con2srv = container_server.ContainerController(
        conf, logger=debug_logger('cont2'))
    obj1srv = the_object_server.ObjectController(
        conf, logger=debug_logger('obj1'))
    obj2srv = the_object_server.ObjectController(
        conf, logger=debug_logger('obj2'))
    obj3srv = the_object_server.ObjectController(
        conf, logger=debug_logger('obj3'))
    obj4srv = the_object_server.ObjectController(
        conf, logger=debug_logger('obj4'))
    obj5srv = the_object_server.ObjectController(
        conf, logger=debug_logger('obj5'))
    obj6srv = the_object_server.ObjectController(
        conf, logger=debug_logger('obj6'))
    context["test_servers"] = \
        (prosrv, acc1srv, acc2srv, con1srv, con2srv, obj1srv, obj2srv, obj3srv,
         obj4srv, obj5srv, obj6srv)
    nl = NullLogger()
    logging_prosv = proxy_logging.ProxyLoggingMiddleware(
        listing_formats.ListingFilter(prosrv), conf, logger=prosrv.logger)
    prospa = spawn(wsgi.server, prolis, logging_prosv, nl)
    acc1spa = spawn(wsgi.server, acc1lis, acc1srv, nl)
    acc2spa = spawn(wsgi.server, acc2lis, acc2srv, nl)
    con1spa = spawn(wsgi.server, con1lis, con1srv, nl)
    con2spa = spawn(wsgi.server, con2lis, con2srv, nl)
    obj1spa = spawn(wsgi.server, obj1lis, obj1srv, nl)
    obj2spa = spawn(wsgi.server, obj2lis, obj2srv, nl)
    obj3spa = spawn(wsgi.server, obj3lis, obj3srv, nl)
    obj4spa = spawn(wsgi.server, obj4lis, obj4srv, nl)
    obj5spa = spawn(wsgi.server, obj5lis, obj5srv, nl)
    obj6spa = spawn(wsgi.server, obj6lis, obj6srv, nl)
    context["test_coros"] = \
        (prospa, acc1spa, acc2spa, con1spa, con2spa, obj1spa, obj2spa, obj3spa,
         obj4spa, obj5spa, obj6spa)
    # Create account
    ts = normalize_timestamp(time.time())
    partition, nodes = prosrv.account_ring.get_nodes('a')
    for node in nodes:
        conn = swift.proxy.controllers.obj.http_connect(node['ip'],
                                                        node['port'],
                                                        node['device'],
                                                        partition, 'PUT', '/a',
                                                        {'X-Timestamp': ts,
                                                         'x-trans-id': 'test'})
        resp = conn.getresponse()
        assert(resp.status == 201)
    # Create another account
    # used for account-to-account tests
    ts = normalize_timestamp(time.time())
    partition, nodes = prosrv.account_ring.get_nodes('a1')
    for node in nodes:
        conn = swift.proxy.controllers.obj.http_connect(node['ip'],
                                                        node['port'],
                                                        node['device'],
                                                        partition, 'PUT',
                                                        '/a1',
                                                        {'X-Timestamp': ts,
                                                         'x-trans-id': 'test'})
        resp = conn.getresponse()
        assert(resp.status == 201)
    # Create containers, 1 per test policy
    sock = connect_tcp(('localhost', prolis.getsockname()[1]))
    fd = sock.makefile()
    fd.write('PUT /v1/a/c HTTP/1.1\r\nHost: localhost\r\n'
             'Connection: close\r\nX-Auth-Token: t\r\n'
             'Content-Length: 0\r\n\r\n')
    fd.flush()
    headers = readuntil2crlfs(fd)
    exp = 'HTTP/1.1 201'
    assert headers[:len(exp)] == exp, "Expected '%s', encountered '%s'" % (
        exp, headers[:len(exp)])
    # Create container in other account
    # used for account-to-account tests
    sock = connect_tcp(('localhost', prolis.getsockname()[1]))
    fd = sock.makefile()
    fd.write('PUT /v1/a1/c1 HTTP/1.1\r\nHost: localhost\r\n'
             'Connection: close\r\nX-Auth-Token: t\r\n'
             'Content-Length: 0\r\n\r\n')
    fd.flush()
    headers = readuntil2crlfs(fd)
    exp = 'HTTP/1.1 201'
    assert headers[:len(exp)] == exp, "Expected '%s', encountered '%s'" % (
        exp, headers[:len(exp)])

    sock = connect_tcp(('localhost', prolis.getsockname()[1]))
    fd = sock.makefile()
    fd.write(
        'PUT /v1/a/c1 HTTP/1.1\r\nHost: localhost\r\n'
        'Connection: close\r\nX-Auth-Token: t\r\nX-Storage-Policy: one\r\n'
        'Content-Length: 0\r\n\r\n')
    fd.flush()
    headers = readuntil2crlfs(fd)
    exp = 'HTTP/1.1 201'
    assert headers[:len(exp)] == exp, \
        "Expected '%s', encountered '%s'" % (exp, headers[:len(exp)])

    sock = connect_tcp(('localhost', prolis.getsockname()[1]))
    fd = sock.makefile()
    fd.write(
        'PUT /v1/a/c2 HTTP/1.1\r\nHost: localhost\r\n'
        'Connection: close\r\nX-Auth-Token: t\r\nX-Storage-Policy: two\r\n'
        'Content-Length: 0\r\n\r\n')
    fd.flush()
    headers = readuntil2crlfs(fd)
    exp = 'HTTP/1.1 201'
    assert headers[:len(exp)] == exp, \
        "Expected '%s', encountered '%s'" % (exp, headers[:len(exp)])
    return context
コード例 #9
0
 def _fake_load(gz_path, stub_objs, metadata_only=False):
     return RingData(devs=stub_objs[os.path.basename(gz_path)[:-8]],
                     replica2part2dev_id=[],
                     part_shift=24)