From 82fa21b9d0553f51b13277539d170805b5058e07 Mon Sep 17 00:00:00 2001 From: annegentle Date: Thu, 5 Sep 2013 16:23:42 -0500 Subject: [PATCH] Removes openstack-object-storage-admin directory, moving content. Moves config info to Config Ref Moves Admin CLI task to Admin User Guide Moves CLI tasks to User Guide Moves Monitoring section to Cloud Admin Guide Removes anything that was a copy/paste from dev docs completely, refers to developer docs instead Change-Id: If201d68c1e72a24c57a61775bc22d1784beea324 Closes-bug: 1216037 --- .../bk-admin-guide-cloud.xml | 10 + .../admin-guide-cloud/ch_objectstorage.xml | 2638 +-- .../section_object-storage-admin.xml | 17 + .../section_object-storage-monitoring.xml} | 9 +- .../common/section_about-object-storage.xml | 13 + .../ch_objectstorageconfigure.xml | 20 +- .../aboutobjectstorage.xml | 134 - .../bk-objectstorage-adminguide.xml | 171 - .../figures/cyberduck_swift_connection.png | Bin 59927 -> 0 bytes .../figures/cyberduck_swift_uploads.png | Bin 63730 -> 0 bytes .../figures/horizon-screenshot.jpg | Bin 133693 -> 0 bytes .../figures/swift_install_arch.png | Bin 60288 -> 0 bytes .../figures/swift_install_arch.svg | 15245 ---------------- .../locale/openstack-object-storage-admin.pot | 3288 ---- .../objectstorage-config-reference.xml | 1493 -- .../objectstorageadmin.xml | 2660 --- .../objectstoragetutorials.xml | 182 - .../openstack-object-storage-admin/pom.xml | 118 - .../openstack-user-admin/src/ch_cli.xml | 2 + .../section_swift_cli_analyze_log_files.xml | 151 + .../src/section_swift_cli_howto.xml | 52 + 21 files changed, 256 insertions(+), 25947 deletions(-) create mode 100644 doc/src/docbkx/admin-guide-cloud/section_object-storage-admin.xml rename doc/src/docbkx/{openstack-object-storage-admin/objectstoragemonitoring.xml => admin-guide-cloud/section_object-storage-monitoring.xml} (98%) create mode 100644 doc/src/docbkx/common/section_about-object-storage.xml delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/figures/cyberduck_swift_connection.png delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/figures/cyberduck_swift_uploads.png delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/figures/horizon-screenshot.jpg delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.png delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.svg delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/locale/openstack-object-storage-admin.pot delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml delete mode 100644 doc/src/docbkx/openstack-object-storage-admin/pom.xml create mode 100644 doc/src/docbkx/openstack-user-admin/src/section_swift_cli_analyze_log_files.xml create mode 100644 doc/src/docbkx/openstack-user/src/section_swift_cli_howto.xml diff --git a/doc/src/docbkx/admin-guide-cloud/bk-admin-guide-cloud.xml b/doc/src/docbkx/admin-guide-cloud/bk-admin-guide-cloud.xml index 1468c0fdae..c24a55fe95 100644 --- a/doc/src/docbkx/admin-guide-cloud/bk-admin-guide-cloud.xml +++ b/doc/src/docbkx/admin-guide-cloud/bk-admin-guide-cloud.xml @@ -44,6 +44,16 @@ + + 2013-09-05 + + + + Moves object storage monitoring section to this guide. + Removes redundant object storage info. + + + 2013-09-03 diff --git a/doc/src/docbkx/admin-guide-cloud/ch_objectstorage.xml b/doc/src/docbkx/admin-guide-cloud/ch_objectstorage.xml index d2c8694890..db79610b23 100644 --- a/doc/src/docbkx/admin-guide-cloud/ch_objectstorage.xml +++ b/doc/src/docbkx/admin-guide-cloud/ch_objectstorage.xml @@ -1,2641 +1,13 @@ + xmlns:xlink="http://www.w3.org/1999/xlink" + version="5.0" + xml:id="ch_admin-openstack-object-storage"> Object Storage OpenStack Object Storage is a scalable object storage system—it is not a file system in the traditional sense. You will not be able to mount this system like traditional SAN or NAS volumes. -
- Introduction to OpenStack Object Storage - This section provides definitions to some key Object Storage concepts. -
- Accounts and account servers - The OpenStack Object Storage system is designed to be used by many different storage - consumers or customers. Each user must identify themselves using an authentication - system. - Nodes that run the Account service are a separate concept from individual accounts. - Account servers are part of the storage system and must be configured along with - Container servers and Object servers. -
-
- Authentication and access permissions - You must authenticate against an Authentication service to receive OpenStack Object - Storage connection parameters and an authentication token. The token must be passed in - for all subsequent container/object operations. One authentication service that you can - use as a middleware example is called swauth and you can download it from - https://github.com/gholt/swauth. You can also integrate with the OpenStack Identity Service, code-named Keystone, which you can download from https://github.com/openstack/keystone. - - Typically the language-specific APIs handle authentication, token passing, and HTTPS - request/response communication. - - - You can implement access control for objects either for users or accounts using - X-Container-Read: accountname and X-Container-Write: accountname:username, which allows - any user from the accountname account to read but only allows the username user from the - accountname account to write. You can also grant public access to objects stored in - OpenStack Object Storage but also limit public access using the Referer header to - prevent site-based content theft such as hot-linking (for example, linking to an image - file from off-site and therefore using other's bandwidth). The public container settings - are used as the default authorization over access control lists. For example, using - X-Container-Read: referer:any allows anyone to read from the container regardless of - other authorization settings. - Generally speaking, each user has their own storage account and has full access to - that account. Users must authenticate with their credentials as described above, but - once authenticated they can create/delete containers and objects within that account. - The only way a user can access the content from another account is if they share an API - access key or a session token provided by your authentication system. -
-
- Containers and objects - A container is a storage compartment for your data and provides a way for you to - organize your data. You can think of a container as a folder in Windows® or a directory in - UNIX®. The primary difference between a container and these other file system concepts is - that containers cannot be nested. You can, however, create an unlimited number of containers - within your account. Data must be stored in a container so you must have at least one - container defined in your account prior to uploading data. - The only restrictions on container names is that they cannot contain a forward slash - (/) or an ascii null (%00) and must be less than 257 bytes in length. - Please note that the length - restriction applies to the name after it has been URL encoded. For example, a container name - of Course Docs would be URL encoded as Course%20Docs and therefore - be 13 bytes in length rather than the expected 11. - - An object is the basic storage entity and any optional metadata that represents the - files you store in the OpenStack Object Storage system. When you upload data to OpenStack Object Storage, the data is - stored as-is (no compression or encryption) and consists of a location (container), the - object's name, and any metadata consisting of key/value pairs. For instance, you may chose - to store a backup of your digital photos and organize them into albums. In this case, each - object could be tagged with metadata such as Album : Caribbean Cruise or - Album : Aspen Ski Trip. - The only restriction on object names is that they must be less than 1024 bytes in length - after URL encoding. For example, an object name of C++final(v2).txt should be - URL encoded as C%2B%2Bfinal%28v2%29.txt and therefore be 24 bytes in length - rather than the expected 16. - The maximum allowable size for a storage object upon upload is 5 gigabytes (GB) and - the minimum is zero bytes. You can use the built-in large object support and the swift - utility to retrieve objects larger than 5 GB. - For metadata, you should not exceed 90 individual key/value pairs for any one object - and the total byte length of all key/value pairs should not exceed 4KB (4096 bytes). - WarningThe Object Storage API uses HTTP which specifies that header - fields, such as those used to send metadata are case insensitive. Please do not expect - the case of metadata items being preserved. -
-
- Operations - Operations are the actions you perform within an OpenStack Object Storage system such - as creating or deleting containers, uploading or downloading objects, and so on. The - full list of operations is documented in the Developer Guide. Operations may be - performed via the REST web service API or a language-specific API; currently, we support - Python, PHP, Java, Ruby, and C#/.NET. - - All operations must include a valid authorization token from your authorization system. - -
- -
- Language-specific API bindings - A set of supported API bindings in several popular languages are available from the - Rackspace Cloud Files product, which uses OpenStack Object Storage code for its - implementation. These bindings provide a layer of abstraction on top of the base REST - API, allowing programmers to work with a container and object model instead of working - directly with HTTP requests and responses. These bindings are free (as in beer and as in - speech) to download, use, and modify. They are all licensed under the MIT License as - described in the COPYING file packaged with each binding. If you do make any - improvements to an API, you are encouraged (but not required) to submit those changes - back to us. - The API bindings for Rackspace Cloud Files are hosted at http://github.com/rackspace. Feel - free to coordinate your changes through github or, if you prefer, send your changes to - cloudfiles@rackspacecloud.com. Just make sure to indicate which language and version you - modified and send a unified diff. - Each binding includes its own documentation (either HTML, PDF, or CHM). They also - include code snippets and examples to help you get started. The currently supported API - binding for OpenStack Object Storage are: - - - PHP (requires 5.x and the modules: cURL, FileInfo, mbstring) - - - Python (requires 2.4 or newer) - - - Java (requires JRE v1.5 or newer) - - - C#/.NET (requires .NET Framework v3.5) - - - Ruby (requires 1.8 or newer and mime-tools module) - - - There are no other supported language-specific bindings at this time. You are welcome - to create your own language API bindings and we can help answer any questions during - development, host your code if you like, and give you full credit for your work. -
-
-
- System administration - By understanding the concepts inherent to the Object Storage system you can better - monitor and administer your storage solution. -
- Object Storage architecture - This section offers a brief overview of each concept in administering Object - Storage. - - The Ring - A ring represents a mapping between the names of entities stored on disk and - their physical location. There are separate rings for accounts, containers, and - objects. When other components need to perform any operation on an object, - container, or account, they need to interact with the appropriate ring to - determine its location in the cluster. - The Ring maintains this mapping using zones, devices, partitions, and - replicas. Each partition in the ring is replicated, by default, 3 times across - the cluster, and the locations for a partition are stored in the mapping - maintained by the ring. The ring is also responsible for determining which - devices are used for hand off in failure scenarios. - Data can be isolated with the concept of zones in the ring. Each replica of a - partition is guaranteed to reside in a different zone. A zone could represent a - drive, a server, a cabinet, a switch, or even a data center. - The partitions of the ring are equally divided among all the devices in the - OpenStack Object Storage installation. When partitions need to be moved around - (for example if a device is added to the cluster), the ring ensures that a - minimum number of partitions are moved at a time, and only one replica of a - partition is moved at a time. - Weights can be used to balance the distribution of partitions on drives across - the cluster. This can be useful, for example, when different sized drives are - used in a cluster. - The ring is used by the Proxy server and several background processes (like - replication). - - - Proxy Server - The Proxy Server is responsible for tying together the rest of the OpenStack - Object Storage architecture. For each request, it will look up the location of - the account, container, or object in the ring (see below) and route the request - accordingly. The public API is also exposed through the Proxy Server. - A large number of failures are also handled in the Proxy Server. For example, - if a server is unavailable for an object PUT, it will ask the ring for a - hand-off server and route there instead. - When objects are streamed to or from an object server, they are streamed - directly through the proxy server to or from the user – the proxy server does - not spool them. - You can use a proxy server with account management enabled by configuring it - in the proxy server configuration file. - - - Object Server - The Object Server is a very simple blob storage server that can store, - retrieve and delete objects stored on local devices. Objects are stored as - binary files on the filesystem with metadata stored in the file’s extended - attributes (xattrs). This requires that the underlying filesystem choice for - object servers support xattrs on files. Some filesystems, like ext3, have xattrs - turned off by default. - Each object is stored using a path derived from the object name’s hash and the - operation’s timestamp. Last write always wins, and ensures that the latest - object version will be served. A deletion is also treated as a version of the - file (a 0 byte file ending with “.ts”, which stands for tombstone). This ensures - that deleted files are replicated correctly and older versions don’t magically - reappear due to failure scenarios. - - - Container Server - The Container Server’s primary job is to handle listings of objects. It does - not’t know where those objects are, just what objects are in a specific - container. The listings are stored as sqlite database files, and replicated - across the cluster similar to how objects are. Statistics are also tracked that - include the total number of objects, and total storage usage for that - container. - - - Account Server - The Account Server is very similar to the Container Server, excepting that it - is responsible for listings of containers rather than objects. - - - Replication - Replication is designed to keep the system in a consistent state in the face - of temporary error conditions like network outages or drive failures. - The replication processes compare local data with each remote copy to ensure - they all contain the latest version. Object replication uses a hash list to - quickly compare subsections of each partition, and container and account - replication use a combination of hashes and shared high water marks. - Replication updates are push based. For object replication, updating is just a - matter of rsyncing files to the peer. Account and container replication push - missing records over HTTP or rsync whole database files. - The replicator also ensures that data is removed from the system. When an item - (object, container, or account) is deleted, a tombstone is set as the latest - version of the item. The replicator will see the tombstone and ensure that the - item is removed from the entire system. - To separate the cluster-internal replication traffic from client traffic, - separate replication servers can be used. These replication servers are based on - the standard storage servers, but they listen on the replication IP and only - respond to REPLICATE requests. Storage servers can serve REPLICATE requests, so - an operator can transition to using a separate replication network with no - cluster downtime. - Replication IP and port information is stored in the ring on a per-node basis. - These parameters will be used if they are present, but they are not required. If - this information does not exist or is empty for a particular node, the node's - standard IP and port will be used for replication. - - - Updaters - There are times when container or account data can not be immediately updated. - This usually occurs during failure scenarios or periods of high load. If an - update fails, the update is queued locally on the file system, and the updater - will process the failed updates. This is where an eventual consistency window - will most likely come in to play. For example, suppose a container server is - under load and a new object is put in to the system. The object will be - immediately available for reads as soon as the proxy server responds to the - client with success. However, the container server did not update the object - listing, and so the update would be queued for a later update. Container - listings, therefore, may not immediately contain the object. - In practice, the consistency window is only as large as the frequency at which - the updater runs and may not even be noticed as the proxy server will route - listing requests to the first container server which responds. The server under - load may not be the one that serves subsequent listing requests – one of the - other two replicas may handle the listing. - - - Auditors - Auditors crawl the local server checking the integrity of the objects, - containers, and accounts. If corruption is found (in the case of bit rot, for - example), the file is quarantined, and replication will replace the bad file - from another replica. If other errors are found they are logged (for example, an - object’s listing can’t be found on any container server it should be). - -
-
- Object layout on storage - Swift uses the underlying filesystem to store the data on disk. An administrator - can use normal filesystem tools to find and inspect this data. Swift uses the - following convention for storing objects: - - /path_to_mount_points/device/objects/partition/hash_suffix/hash/ - Accounts and containers are stored similarly, with the "objects" part of the path - replaced with "accounts" or "containers". - The directory is where all of the data for the object is stored. Inside the - directory, there is normally just one file (named - <timestamp>.data). The - object's data is stored in the file, and the object's metadata is stored in the - extended attributes (xattrs) of the file. - If a user deletes the object, the .data file is deleted and a - <timestamp>.ts ("ts" for - "tombstone") file is created as a zero-byte file. This is a delete marker that will - be eventually reaped, but it exists to ensure that the delete properly propagates to - all replicas in the cluster. - Swift uses this scheme of timestamps in the file name to implement conflict - resolution. Each piece of data is assigned a timestamp by the proxy server when the - request comes to the cluster, and that timestamp is what's used to name the file on - disk on the object (or account or container) server. For the common case, there will - be a single file in the directory. If Swift receives multiple, concurrent requests - to write to the same object, it can happen that multiple .data - files are written to this directory. Swift uses "last-write-wins" to resolve such - conflicts, choosing the most recent file by timestamp. -
-
- Configure and tune Object Storage - This section walks through deployment options and considerations. - You have multiple deployment options to choose from. The swift services run - completely autonomously, which provides for a lot of flexibility when designing the - hardware deployment for swift. The 4 main services are: - - - Proxy Services - - - Object Services - - - Container Services - - - Account Services - - - The Proxy Services are more CPU and network I/O intensive. If you are using 10g - networking to the proxy, or are terminating SSL traffic at the proxy, greater CPU - power will be required. - The Object, Container, and Account Services (Storage Services) are more disk and - network I/O intensive. - The easiest deployment is to install all services on each server. There is nothing - wrong with doing this, as it scales each service out horizontally. - At Rackspace, we put the Proxy Services on their own servers and all of the - Storage Services on the same server. This allows us to send 10g networking to the - proxy and 1g to the storage servers, and keep load balancing to the proxies more - manageable. Storage Services scale out horizontally as storage servers are added, - and we can scale overall API throughput by adding more Proxies. - If you need more throughput to either Account or Container Services, they may each - be deployed to their own servers. For example you might use faster (but more - expensive) SAS or even SSD drives to get faster disk I/O to the databases. - Load balancing and network design is left as an exercise to the reader, but this - is a very important part of the cluster, so time should be spent designing the - network for a Swift cluster. -
-
- Prepare the Ring - - Note - "Partition" in this section refers to the logical partitions of the swift ring - - not physical partitions on Storage node drives. You should setup your Storage - Node disk partitions with one physical partition per disk, according to the - OpenStack Installation Guide. - - The first step is to determine the number of partitions that will be in the ring. - We recommend that there be a minimum of 100 partitions per drive to insure even - distribution across the drives. A good starting point might be to figure out the - maximum number of drives the cluster will contain, and then multiply by 100, and - then round up to the nearest power of two. - For example, imagine we are building a cluster that will have no more than 5,000 - drives. That would mean that we would have a total number of 500,000 partitions, - which is pretty close to 2^19, rounded up. - It is also a good idea to keep the number of partitions small (relatively). The - more partitions there are, the more work that has to be done by the replicators and - other backend jobs and the more memory the rings consume in process. The goal is to - find a good balance between small rings and maximum cluster size. - The next step is to determine the number of replicas to store of the data. - Currently it is recommended to use 3 (as this is the only value that has been - tested). The higher the number, the more storage that is used but the less likely - you are to lose data. - It is also important to determine how many zones the cluster should have. It is - recommended to start with a minimum of 5 zones. You can start with fewer, but our - testing has shown that having at least five zones is optimal when failures occur. We - also recommend trying to configure the zones at as high a level as possible to - create as much isolation as possible. Some example things to take into consideration - can include physical location, power availability, and network connectivity. For - example, in a small cluster you might decide to split the zones up by cabinet, with - each cabinet having its own power and network connectivity. The zone concept is very - abstract, so feel free to use it in whatever way best isolates your data from - failure. Zones are referenced by number, beginning with 1. - You can now start building the ring with: - swift-ring-builder <builder_file> create <part_power> <replicas> <min_part_hours> - This will start the ring build process creating the <builder_file> with - 2^<part_power> partitions. <min_part_hours> is the time in hours before - a specific partition can be moved in succession (24 is a good value for - this). - Devices can be added to the ring with: - swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta> <weight> - This will add a device to the ring where <builder_file> is the name of the - builder file that was created previously, <zone> is the number of the zone - this device is in, <ip> is the ip address of the server the device is in, - <port> is the port number that the server is running on, <device_name> - is the name of the device on the server (for example: sdb1), <meta> is a - string of metadata for the device (optional), and <weight> is a float weight - that determines how many partitions are put on the device relative to the rest of - the devices in the cluster (a good starting point is 100.0 x TB on the drive). Add - each device that will be initially in the cluster. - Once all of the devices are added to the ring, run: - swift-ring-builder <builder_file> rebalance - This will distribute the partitions across the drives in the ring. It is important - whenever making changes to the ring to make all the changes required before running - rebalance. This will ensure that the ring stays as balanced as possible, and as few - partitions are moved as possible. - The above process should be done to make a ring for each storage service (Account, - Container and Object). The builder files will be needed in future changes to the - ring, so it is very important that these be kept and backed up. The resulting - .tar.gz ring file should be pushed to all of the servers in the cluster. For more - information about building rings, running swift-ring-builder with no options will - display help text with available commands and options. -
-
- Considerations and tuning - Fine-tuning your deployment and installation may take some time and effort. Here - are some considerations for improving performance of an OpenStack Object Storage - installation. -
- Memcached considerations - Several of the Services rely on Memcached for caching certain types of - lookups, such as auth tokens, and container/account existence. Swift does not do - any caching of actual object data. Memcached should be able to run on any - servers that have available RAM and CPU. At Rackspace, we run Memcached on the - proxy servers. The memcache_servers config option in the - proxy-server.conf should contain all memcached servers. -
-
- System time - Time may be relative but it is relatively important for Swift! Swift uses - timestamps to determine which is the most recent version of an object. It is - very important for the system time on each server in the cluster to by synced as - closely as possible (more so for the proxy server, but in general it is a good - idea for all the servers). At Rackspace, we use NTP with a local NTP server to - ensure that the system times are as close as possible. This should also be - monitored to ensure that the times do not vary too much. -
-
- General service tuning - Most services support either a worker or concurrency value in the settings. - This allows the services to make effective use of the cores available. A good - starting point to set the concurrency level for the proxy and storage services - to 2 times the number of cores available. If more than one service is sharing a - server, then some experimentation may be needed to find the best balance. - At Rackspace, our Proxy servers have dual quad core processors, giving us 8 - cores. Our testing has shown 16 workers to be a pretty good balance when - saturating a 10g network and gives good CPU utilization. - Our Storage servers all run together on the same servers. These servers have - dual quad core processors, for 8 cores total. We run the Account, Container, and - Object servers with 8 workers each. Most of the background jobs are run at a - concurrency of 1, with the exception of the replicators which are run at a - concurrency of 2. - The above configuration setting should be taken as suggestions and testing of - configuration settings should be done to ensure best utilization of CPU, network - connectivity, and disk I/O. -
-
- RAID considerations - We recommend that you do not use RAID with Swift. - The workload for Swift is very write-heavy, with small random IO accesses. - This type of workload performs very poorly for most parity RAID (e.g., RAID - 2-6). Testing done by Rackspace suggests that under heavy workloads, the overall - RAID performance can degrade to be as slow as a single drive. - Furthermore, a drive failure in a RAID array can result in very poor - performance on the node until the RAID rebuilds, which can take a long time. - Testing at Rackspace, using nodes with 24 2T drives, revealed that a RAID - rebuild after a drive failure could take on the order of two weeks, during which - time the node performance suffered dramatically as the RAID array functioned in - a degraded state. This kind of significantly degraded performance can - potentially have ripple effects across the rest of the cluster. -
-
- Filesystem considerations - Swift is designed to be mostly filesystem agnostic–the only requirement - being that the filesystem supports extended attributes (xattrs). After thorough - testing with our use cases and hardware configurations, XFS was the best - all-around choice. If you decide to use a filesystem other than XFS, we highly - recommend thorough testing. - If you are using XFS, some settings that can dramatically impact performance. - We recommend the following when creating the XFS partition: - mkfs.xfs -i size=1024 -f /dev/sda1 - Setting the inode size is important, as XFS stores xattr data in the inode. If - the metadata is too large to fit in the inode, a new extent is created, which - can cause quite a performance problem. Upping the inode size to 1024 bytes - provides enough room to write the default metadata, plus a little headroom. We - do not recommend running Swift on RAID, but if you are using RAID it is also - important to make sure that the proper sunit and swidth settings get set so that - XFS can make most efficient use of the RAID array. - We also recommend the following example mount options when using XFS: - mount -t xfs -o noatime,nodiratime,nobarrier,logbufs=8 /dev/sda1 - /srv/node/sda - - For a standard swift install, all data drives are mounted directly under - /srv/node (as can be seen in the above example of mounting /dev/sda1 as - /srv/node/sda). If you choose to mount the drives in another directory, be sure - to set the devices config option in all of the server configs to - point to the correct directory. -
-
- General system tuning - Rackspace currently runs Swift on Ubuntu Server 10.04, and the following - changes have been found to be useful for our use cases. - The following settings should be in /etc/sysctl.conf: - - -# disable TIME_WAIT.. wait.. -net.ipv4.tcp_tw_recycle=1 -net.ipv4.tcp_tw_reuse=1 - -# disable syn cookies -net.ipv4.tcp_syncookies = 0 - -# double amount of allowed conntrack -net.ipv4.netfilter.ip_conntrack_max = 262144 - - - To load the updated sysctl settings, run sudo sysctl -p - A note about changing the TIME_WAIT values. By default the OS will hold a port - open for 60 seconds to ensure that any remaining packets can be received. During - high usage, and with the number of connections that are created, it is easy to - run out of ports. We can change this since we are in control of the network. If - you are not in control of the network, or do not expect high loads, then you may - not want to adjust those values. - Another helpful tuning parameter on slower systems that helps to ensure enough - time is allowed for service restarts is the -k N (or - --kill-wait N) parameter of - swift-init. This allows you to change the default (15 second) - time (N, in seconds) that swift waits for processes to die and notably you can - pass --run-dir flag with swift-init to set - where PIDs will be stored. -
-
- Logging considerations - Swift is set up to log directly to syslog. Every service can be configured - with the log_facility option to set the syslog log facility - destination. We recommend using syslog-ng to route the logs to specific log - files locally on the server and also to remote log collecting servers. -
-
- Working with rings - The rings determine where data should reside in the cluster. There is a - separate ring for account databases, container databases, and individual objects - but each ring works in the same way. These rings are externally managed, in that - the server processes themselves do not modify the rings, they are instead given - new rings modified by other tools. - The ring uses a configurable number of bits from a path's MD5 hash as a - partition index that designates a device. The number of bits kept from the hash - is known as the partition power, and 2 to the partition power indicates the - partition count. Partitioning the full MD5 hash ring allows other parts of the - cluster to work in batches of items at once which ends up either more efficient - or at least less complex than working with each item separately or the entire - cluster all at once. - Another configurable value is the replica count, which indicates how many of - the partition->device assignments comprise a single ring. For a given - partition number, each replica's device will not be in the same zone as any - other replica's device. Zones can be used to group devices based on physical - locations, power separations, network separations, or any other attribute that - would lessen multiple replicas being unavailable at the same time. -
- Managing rings with the ring-builder - The rings are built and managed manually by a utility called the - ring-builder. The ring-builder assigns partitions to devices and writes an - optimized Python structure to a gzipped, pickled file on disk for shipping - out to the servers. The server processes just check the modification time of - the file occasionally and reload their in-memory copies of the ring - structure as needed. Because of how the ring-builder manages changes to the - ring, using a slightly older ring usually just means one of the three - replicas for a subset of the partitions will be incorrect, which can be - easily worked around. - The ring-builder also keeps its own builder file with the ring information - and additional data required to build future rings. It is very important to - keep multiple backup copies of these builder files. One option is to copy - the builder files out to every server while copying the ring files - themselves. Another is to upload the builder files into the cluster itself. - Complete loss of a builder file will mean creating a new ring from scratch, - nearly all partitions will end up assigned to different devices, and - therefore nearly all data stored will have to be replicated to new - locations. So, recovery from a builder file loss is possible, but data will - definitely be unreachable for an extended time. -
- About the ring data structure - The ring data structure consists of three top level fields: a list of - devices in the cluster, a list of lists of device ids indicating - partition to device assignments, and an integer indicating the number of - bits to shift an MD5 hash to calculate the partition for the - hash. -
- List of devices in the ring - The list of devices is known internally to the Ring class as devs. - Each item in the list of devices is a dictionary with the following - keys: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
List of devices and keys
KeyTypeDescription
idintegerThe index into the list devices.
zoneintegerThe zone the devices resides in.
weightfloatThe relative weight of the device in comparison to other - devices. This usually corresponds directly to the amount - of disk space the device has compared to other devices. - For instance a device with 1 tera byte of space might - have a weight of 100.0 and another device with 2 tera - bytes of space might have a weight of 200.0. This weight - can also be used to bring back into balance a device - that has ended up with more or less data than desired - over time. A good average weight of 100.0 allows - flexibility in lowering the weight later if - necessary.
ipstringThe IP address of the server containing the device.
portintThe TCP port the listening server process uses that - serves requests for the device.
replication_ipstringThe IP address of the server containing the device in - the replication network.
replication_portintThe TCP port the listening replication server process - uses that serves replication requests for the - device.
devicestringThe on disk name of the device on the server. For - example: sdb1
metastringA general-use field for storing additional information - for the device. This information isn't used directly by - the server processes, but can be useful in debugging. - For example, the date and time of installation and - hardware manufacturer could be stored here.
- Note: The list of devices may contain holes, or indexes set to - None, for devices that have been removed from the cluster. - Generally, device ids are not reused. Also, some devices may be - temporarily disabled by setting their weight to 0.0. -
-
-
- Partition assignment list - This is a list of array(‘I') of devices ids. The outermost list - contains an array(‘I') for each replica. Each array(‘I') has - a length equal to the partition count for the ring. Each integer in the - array(‘I') is an index into the above list of devices. The - partition list is known internally to the Ring class as - _replica2part2dev_id. - So, to create a list of device dictionaries assigned to a partition, - the Python code would look like: devices = - [self.devs[part2dev_id[partition]] for part2dev_id in - self._replica2part2dev_id] - array(‘I') is used for memory conservation as there may be - millions of partitions. -
-
- Partition shift value - The partition shift value is known internally to the Ring class as - _part_shift. This value used to shift an MD5 hash to calculate the - partition on which the data for that hash should reside. Only the top - four bytes of the hash is used in this process. For example, to compute - the partition for the path /account/container/object the Python code - might look like: partition = unpack_from('>I', - md5('/account/container/object').digest())[0] - >>self._part_shift -
-
-
- Building the ring - The initial building of the ring first calculates the number of partitions - that should ideally be assigned to each device based the device's weight. - For example, if the partition power of 20 the ring will have 1,048,576 - partitions. If there are 1,000 devices of equal weight they will each desire - 1,048.576 partitions. The devices are then sorted by the number of - partitions they desire and kept in order throughout the initialization - process. - Then, the ring builder assigns each partition's replica to the device that - desires the most partitions at that point, with the restriction that the - device is not in the same zone as any other replica for that partition. Once - assigned, the device's desired partition count is decremented and moved to - its new sorted location in the list of devices and the process - continues. - When building a new ring based on an old ring, the desired number of - partitions each device wants is recalculated. Next the partitions to be - reassigned are gathered up. Any removed devices have all their assigned - partitions unassigned and added to the gathered list. Any devices that have - more partitions than they now desire have random partitions unassigned from - them and added to the gathered list. Lastly, the gathered partitions are - then reassigned to devices using a similar method as in the initial - assignment described above. - Whenever a partition has a replica reassigned, the time of the - reassignment is recorded. This is taken into account when gathering - partitions to reassign so that no partition is moved twice in a configurable - amount of time. This configurable amount of time is known internally to the - RingBuilder class as min_part_hours. This restriction is ignored for - replicas of partitions on devices that have been removed, as removing a - device only happens on device failure and there's no choice but to make a - reassignment. - The above processes don't always perfectly rebalance a ring due to the - random nature of gathering partitions for reassignment. To help reach a more - balanced ring, the rebalance process is repeated until near perfect (less 1% - off) or when the balance doesn't improve by at least 1% (indicating we - probably can't get perfect balance due to wildly unbalanced zones or too - many partitions recently moved). -
-
- History of the ring design - The ring code went through many iterations before arriving at what it is - now and while it has been stable for a while now, the algorithm may be - tweaked or perhaps even fundamentally changed if new ideas emerge. This - section will try to describe the previous ideas attempted and attempt to - explain why they were discarded. - A “live ring” option was considered where each server could - maintain its own copy of the ring and the servers would use a gossip - protocol to communicate the changes they made. This was discarded as too - complex and error prone to code correctly in the project time span - available. One bug could easily gossip bad data out to the entire cluster - and be difficult to recover from. Having an externally managed ring - simplifies the process, allows full validation of data before it's shipped - out to the servers, and guarantees each server is using a ring from the same - time line. It also means that the servers themselves aren't spending a lot - of resources maintaining rings. - A couple of “ring server” options were considered. One was - where all ring lookups would be done by calling a service on a separate - server or set of servers, but this was discarded due to the latency - involved. Another was much like the current process but where servers could - submit change requests to the ring server to have a new ring built and - shipped back out to the servers. This was discarded due to project time - constraints and because ring changes are currently infrequent enough that - manual control was sufficient. However, lack of quick automatic ring changes - did mean that other parts of the system had to be coded to handle devices - being unavailable for a period of hours until someone could manually update - the ring. - The current ring process has each replica of a partition independently - assigned to a device. A version of the ring that used a third of the memory - was tried, where the first replica of a partition was directly assigned and - the other two were determined by “walking” the ring until - finding additional devices in other zones. This was discarded as control was - lost as to how many replicas for a given partition moved at once. Keeping - each replica independent allows for moving only one partition replica within - a given time window (except due to device failures). Using the additional - memory was deemed a good trade off for moving data around the cluster much - less often. - Another ring design was tried where the partition to device assignments - weren't stored in a big list in memory but instead each device was assigned - a set of hashes, or anchors. The partition would be determined from the data - item's hash and the nearest device anchors would determine where the - replicas should be stored. However, to get reasonable distribution of data - each device had to have a lot of anchors and walking through those anchors - to find replicas started to add up. In the end, the memory savings wasn't - that great and more processing power was used, so the idea was - discarded. - A completely non-partitioned ring was also tried but discarded as the - partitioning helps many other parts of the system, especially replication. - Replication can be attempted and retried in a partition batch with the other - replicas rather than each data item independently attempted and retried. - Hashes of directory structures can be calculated and compared with other - replicas to reduce directory walking and network traffic. - Partitioning and independently assigning partition replicas also allowed - for the best balanced cluster. The best of the other strategies tended to - give +-10% variance on device balance with devices of equal weight and +-15% - with devices of varying weights. The current strategy allows us to get +-3% - and +-8% respectively. - Various hashing algorithms were tried. SHA offers better security, but the - ring doesn't need to be cryptographically secure and SHA is slower. Murmur - was much faster, but MD5 was built-in and hash computation is a small - percentage of the overall request handling time. In all, once it was decided - the servers wouldn't be maintaining the rings themselves anyway and only - doing hash lookups, MD5 was chosen for its general availability, good - distribution, and adequate speed. -
-
-
- The Account Reaper - The Account Reaper removes data from deleted accounts in the - background. - An account is marked for deletion by a reseller through the services server's - remove_storage_account XMLRPC call. This simply puts the value DELETED into the - status column of the account_stat table in the account database (and replicas), - indicating the data for the account should be deleted later. There is no set - retention time and no undelete; it is assumed the reseller will implement such - features and only call remove_storage_account once it is truly desired the - account's data be removed. - The account reaper runs on each account server and scans the server - occasionally for account databases marked for deletion. It will only trigger on - accounts that server is the primary node for, so that multiple account servers - aren't all trying to do the same work at the same time. Using multiple servers - to delete one account might improve deletion speed, but requires coordination so - they aren't duplicating effort. Speed really isn't as much of a concern with - data deletion and large accounts aren't deleted that often. - The deletion process for an account itself is pretty straightforward. For each - container in the account, each object is deleted and then the container is - deleted. Any deletion requests that fail won't stop the overall process, but - will cause the overall process to fail eventually (for example, if an object - delete times out, the container won't be able to be deleted later and therefore - the account won't be deleted either). The overall process continues even on a - failure so that it doesn't get hung up reclaiming cluster space because of one - troublesome spot. The account reaper will keep trying to delete an account until - it eventually becomes empty, at which point the database reclaim process within - the db_replicator will eventually remove the database files. - If the account reaper fails to clean up an account after a specified time, the - reaper logs a message. Search your system for such messages. Set the - reap_warn_after configuration variable to define the - frequency of message alerts. The default is 30 days. -
- Account Reaper background - At first, a simple approach of deleting an account through completely - external calls was considered as it required no changes to the system. All - data would simply be deleted in the same way the actual user would, through - the public REST API. However, the downside was that it would use proxy - resources and log everything when it didn't really need to. Also, it would - likely need a dedicated server or two, just for issuing the delete - requests. - A completely bottom-up approach was also considered, where the object and - container servers would occasionally scan the data they held and check if - the account was deleted, removing the data if so. The upside was the speed - of reclamation with no impact on the proxies or logging, but the downside - was that nearly 100% of the scanning would result in no action creating a - lot of I/O load for no reason. - A more container server centric approach was also considered, where the - account server would mark all the containers for deletion and the container - servers would delete the objects in each container and then themselves. This - has the benefit of still speedy reclamation for accounts with a lot of - containers, but has the downside of a pretty big load spike. The process - could be slowed down to alleviate the load spike possibility, but then the - benefit of speedy reclamation is lost and what's left is just a more complex - process. Also, scanning all the containers for those marked for deletion - when the majority wouldn't be seemed wasteful. The db_replicator could do - this work while performing its replication scan, but it would have to spawn - and track deletion processes which seemed needlessly complex. - In the end, an account server centric approach seemed best, as described - above. -
-
-
-
- Replication - Since each replica in OpenStack Object Storage functions independently, and - clients generally require only a simple majority of nodes responding to consider an - operation successful, transient failures like network partitions can quickly cause - replicas to diverge. These differences are eventually reconciled by asynchronous, - peer-to-peer replicator processes. The replicator processes traverse their local - filesystems, concurrently performing operations in a manner that balances load - across physical disks. - Replication uses a push model, with records and files generally only being copied - from local to remote replicas. This is important because data on the node may not - belong there (as in the case of and ring changes), and a replicator can't know what - data exists elsewhere in the cluster that it should pull in. It's the duty of any - node that contains data to ensure that data gets to where it belongs. Replica - placement is handled by the ring. - Every deleted record or file in the system is marked by a tombstone, so that - deletions can be replicated alongside creations. These tombstones are cleaned up by - the replication process after a period of time referred to as the consistency - window, which is related to replication duration and how long transient failures can - remove a node from the cluster. Tombstone cleanup must be tied to replication to - reach replica convergence. - If a replicator detects that a remote drive has failed, it will use the ring's - “get_more_nodes” interface to choose an alternate node to synchronize - with. The replicator can generally maintain desired levels of replication in the - face of hardware failures, though some replicas may not be in an immediately usable - location. - Replication is an area of active development, and likely rife with potential - improvements to speed and correctness. - There are two major classes of replicator - the db replicator, which replicates - accounts and containers, and the object replicator, which replicates object - data. -
- Database replication - The first step performed by db replication is a low-cost hash comparison to - find out whether or not two replicas already match. Under normal operation, this - check is able to verify that most databases in the system are already - synchronized very quickly. If the hashes differ, the replicator brings the - databases in sync by sharing records added since the last sync point. - This sync point is a high water mark noting the last record at which two - databases were known to be in sync, and is stored in each database as a tuple of - the remote database id and record id. Database ids are unique amongst all - replicas of the database, and record ids are monotonically increasing integers. - After all new records have been pushed to the remote database, the entire sync - table of the local database is pushed, so the remote database knows it's now in - sync with everyone the local database has previously synchronized with. - If a replica is found to be missing entirely, the whole local database file is - transmitted to the peer using rsync(1) and vested with a new unique id. - In practice, DB replication can process hundreds of databases per concurrency - setting per second (up to the number of available CPUs or disks) and is bound by - the number of DB transactions that must be performed. -
-
- Object replication - The initial implementation of object replication simply performed an rsync to - push data from a local partition to all remote servers it was expected to exist - on. While this performed adequately at small scale, replication times - skyrocketed once directory structures could no longer be held in RAM. We now use - a modification of this scheme in which a hash of the contents for each suffix - directory is saved to a per-partition hashes file. The hash for a suffix - directory is invalidated when the contents of that suffix directory are - modified. - The object replication process reads in these hash files, calculating any - invalidated hashes. It then transmits the hashes to each remote server that - should hold the partition, and only suffix directories with differing hashes on - the remote server are rsynced. After pushing files to the remote server, the - replication process notifies it to recalculate hashes for the rsynced suffix - directories. - Performance of object replication is generally bound by the number of uncached - directories it has to traverse, usually as a result of invalidated suffix - directory hashes. Using write volume and partition counts from our running - systems, it was designed so that around 2% of the hash space on a normal node - will be invalidated per day, which has experimentally given us acceptable - replication speeds. -
-
-
- Manage large objects (Greater than 5 GB) - OpenStack Object Storage has a limit on the size of a single uploaded object; by - default this is 5GB. However, the download size of a single object is virtually - unlimited with the concept of segmentation. Segments of the larger object are - uploaded and a special manifest file is created that, when downloaded, sends all the - segments concatenated as a single object. This also offers much greater upload speed - with the possibility of parallel uploads of the segments. -
- Use Swift to manage segmented objects - The quickest way to try out this feature is use the included swift Object - Storage client tool. You can use the -S option to specify the segment size to - use when splitting a large file. For example: - # swift upload test_container -S 1073741824 large_file - This would split the large_file into 1G segments and begin uploading those - segments in parallel. Once all the segments have been uploaded, swift will then - create the manifest file so the segments can be downloaded as one. - So now, the following st command would download the entire large - object: - swift download test_container large_file - The swift CLI uses a strict convention for its segmented object support. In - the above example it will upload all the segments into a second container named - test_container_segments. These segments will have names like - large_file/1290206778.25/21474836480/00000000, - large_file/1290206778.25/21474836480/00000001, etc. - The main benefit for using a separate container is that the main container - listings will not be polluted with all the segment names. The reason for using - the segment name format of - <name>/<timestamp>/<size>/<segment> is so that an upload - of a new file with the same name won't overwrite the contents of the first until - the last moment when the manifest file is updated. - The swift CLI will manage these segment files for you, deleting old segments - on deletes and overwrites, etc. You can override this behavior with the - --leave-segments option if desired; this is useful if you want to have multiple - versions of the same large object available. -
-
- Direct API management of large objects - You can also work with the segments and manifests directly with HTTP requests - instead of having swift do that for you. You can just upload the segments like - you would any other object and the manifest is just a zero-byte file with an - extra X-Object-Manifest header. - All the object segments need to be in the same container, have a common object - name prefix, and their names sort in the order they should be concatenated. They - don't have to be in the same container as the manifest file will be, which is - useful to keep container listings clean as explained above with st. - The manifest file is simply a zero-byte file with the extra - X-Object-Manifest:<container>/<prefix> header, - where <container> is the container the object segments are in and - <prefix> is the common prefix for all the segments. - It is best to upload all the segments first and then create or update the - manifest. In this way, the full object won't be available for downloading until - the upload is complete. Also, you can upload a new set of segments to a second - location and then update the manifest to point to this new location. During the - upload of the new segments, the original manifest will still be available to - download the first set of segments. - Here's an example using curl with tiny 1-byte segments: - # First, upload the segments - -$ curl -X PUT -H 'X-Auth-Token: <token>' http://<storage_url>/container/myobject/1 --data-binary '1' -$ curl -X PUT -H 'X-Auth-Token: <token>' http://<storage_url>/container/myobject/2 --data-binary '2' -$ curl -X PUT -H 'X-Auth-Token: <token>' http://<storage_url>/container/myobject/3 --data-binary '3' - - # Next, create the manifest file curl -X PUT -H 'X-Auth-Token: <token>' \ - -H 'X-Object-Manifest: container/myobject/' \ - http://<storage_url>/container/myobject --data-binary '' # And now we can - download the segments as a single object curl -H 'X-Auth-Token: <token>' \ - http://<storage_url>/container/myobject -
-
- Additional notes on large objects - - - With a GET or HEAD of a manifest file, the X-Object-Manifest: - <container>/<prefix> header will be - returned with the concatenated object so you can tell where it's getting - its segments from. - - - The response's Content-Length for a GET or HEAD on the manifest file - will be the sum of all the segments in the - <container>/<prefix> listing, dynamically. So, uploading - additional segments after the manifest is created will cause the - concatenated object to be that much larger; there's no need to recreate - the manifest file. - - - The response's Content-Type for a GET or HEAD on the manifest will be - the same as the Content-Type set during the PUT request that created the - manifest. You can easily change the Content-Type by reissuing the - PUT. - - - The response's ETag for a GET or HEAD on the manifest file will be the - MD5 sum of the concatenated string of ETags for each of the segments in - the <container>/<prefix> listing, dynamically. Usually in - OpenStack Object Storage the ETag is the MD5 sum of the contents of the - object, and that holds true for each segment independently. But, it's - not feasible to generate such an ETag for the manifest itself, so this - method was chosen to at least offer change detection. - - -
-
- Large object storage background - Large object support has gone through various iterations before settling on - this implementation. - The primary factor driving the limitation of object size in OpenStack Object - Storage is maintaining balance among the partitions of the ring. To maintain an - even dispersion of disk usage throughout the cluster the obvious storage pattern - was to simply split larger objects into smaller segments, which could then be - glued together during a read. - Before the introduction of large object support some applications were already - splitting their uploads into segments and re-assembling them on the client side - after retrieving the individual pieces. This design allowed the client to - support backup and archiving of large data sets, but was also frequently - employed to improve performance or reduce errors due to network interruption. - The major disadvantage of this method is that knowledge of the original - partitioning scheme is required to properly reassemble the object, which is not - practical for some use cases, such as CDN origination. - In order to eliminate any barrier to entry for clients wanting to store - objects larger than 5GB, initially we also prototyped fully transparent support - for large object uploads. A fully transparent implementation would support a - larger max size by automatically splitting objects into segments during upload - within the proxy without any changes to the client API. All segments were - completely hidden from the client API. - This solution introduced a number of challenging failure conditions into the - cluster, wouldn't provide the client with any option to do parallel uploads, and - had no basis for a resume feature. The transparent implementation was deemed - just too complex for the benefit. - The current “user manifest” design was chosen in order to provide - a transparent download of large objects to the client and still provide the - uploading client a clean API to support segmented uploads. - Alternative “explicit” user manifest options were discussed which - would have required a predefined format for listing the segments to - “finalize” the segmented upload. While this may offer some potential - advantages, it was decided that pushing an added burden onto the client which - could potentially limit adoption should be avoided in favor of a simpler - “API” (essentially just the format of the ‘X-Object-Manifest' - header). - During development it was noted that this “implicit” user manifest - approach which is based on the path prefix can be potentially affected by the - eventual consistency window of the container listings, which could theoretically - cause a GET on the manifest object to return an invalid whole object for that - short term. In reality you're unlikely to encounter this scenario unless you're - running very high concurrency uploads against a small testing environment which - isn't running the object-updaters or container-replicators. - Like all of OpenStack Object Storage, Large Object Support is living feature - which will continue to improve and may change over time. -
-
-
- Throttle resources by setting rate limits - Rate limiting in OpenStack Object Storage is implemented as a pluggable middleware - that you configure on the proxy server. Rate limiting is performed on requests that - result in database writes to the account and container sqlite dbs. It uses memcached - and is dependent on the proxy servers having highly synchronized time. The rate - limits are limited by the accuracy of the proxy server clocks. -
- Configure for rate limiting - All configuration is optional. If no account or container limits are provided - there will be no rate limiting. Configuration available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for rate limiting in proxy-server.conf - file
OptionDefaultDescription
clock_accuracy1000Represents how accurate the proxy servers' system clocks are with - each other. 1000 means that all the proxies' clock are accurate to - each other within 1 millisecond. No rate limit should be higher than - the clock accuracy.
max_sleep_time_seconds60App will immediately return a 498 response if the necessary sleep - time ever exceeds the given max_sleep_time_seconds.
log_sleep_time_seconds0To allow visibility into rate limiting set this value > 0 and all - sleeps greater than the number will be logged.
log_nameswiftLabel used when logging
log_facilityLOG_LOCAL0Syslog log facility
log_levelINFOLogging level
log_headersFalseIf True, log headers in each request
account_ratelimit0If set, will limit all requests to /account_name and PUTs to - /account_name/container_name. Number is in requests per second
account_whitelist‘'Comma separated lists of account names that will not be rate - limited.
account_blacklist‘'Comma separated lists of account names that will not be allowed. - Returns a 497 response.
container_ratelimit_size‘'When set with container_limit_x = r: for containers of size x, limit - requests per second to r. Will limit GET and HEAD requests to - /account_name/container_name and PUTs and DELETEs to - /account_name/container_name/object_name
rate_buffer_seconds5Number of seconds the rate counter can drop and be allowed to catch - up (faster than the listed rate). A larger number will result in - larger average spikes but better average accuracy.
- The container rate limits are linearly interpolated from the values given. A - sample container rate limiting could be: - container_ratelimit_100 = 100 - container_ratelimit_200 = 50 - container_ratelimit_500 = 20 - This would result in - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Values for Rate Limiting with Sample Configuration Settings
Container SizeRate Limit
0-99No limiting
100100
15075
50020
100020
-
-
-
- Additional features - This section aims to detail a number of additional features in Swift and their - configuration. -
- Health check - Health Check provides a simple way to monitor if the swift proxy server is - alive. If the proxy is access with the path /healthcheck, it will respond with - “OK” in the body, which can be used by monitoring tools. - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for filter:healthcheck in proxy-server.conf - file
OptionDefaultDescription
log_nameswiftLabel used when logging
log_facilityLOG_LOCAL0Syslog log facility
log_levelINFOLogging level
-
-
- Domain Remap - Domain Remap is middleware that translates container and account parts of a - domain to path parameters that the proxy server understands. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for filter:domain_remap in proxy-server.conf - file
OptionDefaultDescription
log_nameswiftLabel used when logging
log_facilityLOG_LOCAL0Syslog log facility
log_levelINFOLogging level
log_headersFalseIf True, log headers in each request
path_rootv1Root path
reseller_prefixesAUTHReseller prefix
storage_domainexample.comDomain to use for remap
-
-
- CNAME lookup - CNAME Lookup is middleware that translates an unknown domain in the host - header to something that ends with the configured storage_domain by looking up - the given domain's CNAME record in DNS. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for filter:cname_lookup in proxy-server.conf - file
OptionDefaultDescription
log_nameswiftLabel used when logging
log_facilityLOG_LOCAL0Syslog log facility
log_levelINFOLogging level
log_headersFalseIf True, log headers in each request
lookup_depth1As CNAMEs can be recursive, how many levels to search through.
storage_domainexample.conf -
-
-
- Temporary URL - Allows the creation of URLs to provide temporary access to objects. For - example, a website may wish to provide a link to download a large object in - Swift, but the Swift account has no public access. The website can generate a - URL that will provide GET access for a limited time to the resource. When the - web browser user clicks on the link, the browser will download the object - directly from Swift, obviating the need for the website to act as a proxy for - the request. If the user were to share the link with all his friends, or - accidentally post it on a forum, etc. the direct access would be limited to the - expiration time set when the website created the link. To create such temporary - URLs, first an X-Account-Meta-Temp-URL-Key header must be set on the Swift - account. Then, an HMAC-SHA1 (RFC 2104) signature is generated using the HTTP - method to allow (GET or PUT), the Unix timestamp the access should be allowed - until, the full path to the object, and the key set on the account. For example, - here is code generating the signature for a GET for 60 seconds on - /v1/AUTH_account/container/object: - - import hmac - from hashlib import sha1 - from time import time - method = 'GET' - expires = int(time() + 60) - path = '/v1/AUTH_account/container/object' - key = 'mykey' - hmac_body = '%s\n%s\n%s' % (method, expires, path) - sig = hmac.new(key, hmac_body, sha1).hexdigest() - - Be certain to use the full path, from the /v1/ onward. Let's say the sig ends - up equaling da39a3ee5e6b4b0d3255bfef95601890afd80709 and expires ends up - 1323479485. Then, for example, the website could provide a link to: - - https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485 - - Any alteration of the resource path or query arguments would result in 401 - Unauthorized. Similarly, a PUT where GET was the allowed method would 401. HEAD - is allowed if GET or PUT is allowed. Using this in combination with browser form - post translation middleware could also allow direct-from-browser uploads to - specific locations in Swift. Note that changing the X-Account-Meta-Temp-URL-Key - will invalidate any previously generated temporary URLs within 60 seconds (the - memcache time for the key). - A script called swift-temp-url distributed with swift source code eases the - temporary URL creation: - - $ bin/swift-temp-url GET 3600 /v1/AUTH_account/container/object mykey - /v1/AUTH_account/container/object? - temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91& - temp_url_expires=1374497657 - - The path returned by the above command is prefixed with swift storage - hostname. - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for filter:tempurl in proxy-server.conf - file
OptionDefaultDescription
incoming_allow_headers - -
incoming_remove_headersx-timestamp -
outgoing_allow_headersx-object-meta-public-* -
outgoing_remove_headersx-object-meta-* -
-
-
- Name check filter - The name check is a filter that disallows any paths that contain defined - forbidden characters or that exceed a defined length. - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for filter:name_check in proxy-server.conf - file
OptionDefaultDescription
forbidden_chars - Characters that are not allowed in a name
max_length255Maximum length of a name
forbidden_regexp"/\./|/\.\./|/\.$|/\.\.$"Substrings to forbid, using regular expression syntax
-
-
- Constraints - The swift-constraints section in - swift.conf allows modification of internal limits within - swift. These are advanced features for tuning the performance of the cluster and - should be altered with caution. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for swift-constraints in swift.conf
OptionDefaultDescription
max_file_size5368709122the 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_meta_name_length128the max number of bytes in the utf8 encoding of the name portion of - a metadata header.
max_meta_value_lenth256the max number of bytes in the utf8 encoding of a metadata - value
max_meta_count90the max number of metadata keys that can be stored on a single - account, container, or object
max_meta_overall_size4096the max number of bytes in the utf8 encoding of the metadata (keys + - values)
max_object_name_length1024the max number of bytes in the utf8 encoding of an object name
container_listing_limit10000the default (and max) number of items returned for a container - listing request
max_account_name_length256the max number of bytes in the utf8 encoding of an account name
max_container_name_length256the max number of bytes in the utf8 encoding of a container - name
-
-
- Cluster health - There is a swift-dispersion-report tool for measuring - overall cluster health. This is accomplished by checking if a set of - deliberately distributed containers and objects are currently in their proper - places within the cluster. For instance, a common deployment has three replicas - of each object. The health of that object can be measured by checking if each - replica is in its proper place. If only 2 of the 3 is in place the object’s - heath can be said to be at 66.66%, where 100% would be perfect. A single - object’s health, especially an older object, usually reflects the health of that - entire partition the object is in. If we make enough objects on a distinct - percentage of the partitions in the cluster, we can get a pretty valid estimate - of the overall cluster health. In practice, about 1% partition coverage seems to - balance well between accuracy and the amount of time it takes to gather results. - The first thing that needs to be done to provide this health value is create a - new account solely for this usage. Next, we need to place the containers and - objects throughout the system so that they are on distinct partitions. The - swift-dispersion-populate tool does this by making up random container and - object names until they fall on distinct partitions. Last, and repeatedly for - the life of the cluster, we need to run the swift-dispersion-report tool to - check the health of each of these containers and objects. These tools need - direct access to the entire cluster and to the ring files (installing them on a - proxy server will probably do). Both swift-dispersion-populate and - swift-dispersion-report use the same configuration file, - /etc/swift/dispersion.conf. Example dispersion.conf file: - -[dispersion] -auth_url = http://localhost:8080/auth/v1.0 -auth_user = test:tester -auth_key = testing - - There are also options for the conf file for specifying the dispersion coverage - (defaults to 1%), retries, concurrency, etc. though usually the defaults are - fine. Once the configuration is in place, run swift-dispersion-populate to - populate the containers and objects throughout the cluster. Now that those - containers and objects are in place, you can run swift-dispersion-report to get - a dispersion report, or the overall health of the cluster. Here is an example of - a cluster in perfect health: - -$ swift-dispersion-report -Queried 2621 containers for dispersion reporting, 19s, 0 retries -100.00% of container copies found (7863 of 7863) -Sample represents 1.00% of the container partition space - -Queried 2619 objects for dispersion reporting, 7s, 0 retries -100.00% of object copies found (7857 of 7857) -Sample represents 1.00% of the object partition space - - Now, deliberately double the weight of a device in the object ring (with - replication turned off) and rerun the dispersion report to show what impact that - has: - -$ swift-ring-builder object.builder set_weight d0 200 -$ swift-ring-builder object.builder rebalance -... -$ swift-dispersion-report -Queried 2621 containers for dispersion reporting, 8s, 0 retries -100.00% of container copies found (7863 of 7863) -Sample represents 1.00% of the container partition space - -Queried 2619 objects for dispersion reporting, 7s, 0 retries -There were 1763 partitions missing one copy. -77.56% of object copies found (6094 of 7857) -Sample represents 1.00% of the object partition space - - You can see the health of the objects in the cluster has gone down - significantly. Of course, this test environment has just four devices, in a - production environment with many devices the impact of one device change is much - less. Next, run the replicators to get everything put back into place and then - rerun the dispersion report: - -... start object replicators and monitor logs until they're caught up ... -$ swift-dispersion-report -Queried 2621 containers for dispersion reporting, 17s, 0 retries -100.00% of container copies found (7863 of 7863) -Sample represents 1.00% of the container partition space - -Queried 2619 objects for dispersion reporting, 7s, 0 retries -100.00% of object copies found (7857 of 7857) -Sample represents 1.00% of the object partition space - - Alternatively, the dispersion report can also be output in json format. This - allows it to be more easily consumed by third party utilities: - -$ swift-dispersion-report -j -{"object": {"retries:": 0, "missing_two": 0, "copies_found": 7863, "missing_one": 0, -"copies_expected": 7863, "pct_found": 100.0, "overlapping": 0, "missing_all": 0}, "container": -{"retries:": 0, "missing_two": 0, "copies_found": 12534, "missing_one": 0, "copies_expected": -12534, "pct_found": 100.0, "overlapping": 15, "missing_all": 0}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration options for dispersion in proxy-server.conf - file
OptionDefaultDescription
auth_version1.0Swift authentication API version
dispersion_coverage1.0 -
dump_json'no' -
retries3 -
auth_url - -
auth_user - -
auth_key - -
swift_dir/etc/swift -
-
-
- Static Large Object (SLO) support - This feature is very similar to Dynamic Large Object (DLO) support in that it - allows the user to upload many objects concurrently and afterwards download them - as a single object. It is different in that it does not rely on eventually - consistent container listings to do so. Instead, a user defined manifest of the - object segments is used. -
- Uploading the manifest - After the user has uploaded the objects to be concatenated a manifest is - uploaded. The request must be a PUT with the query parameter:: - ?multipart-manifest=put The body of this - request will be an ordered list of files in json data format. The data to be - supplied for each segment is: - - path: the path to the segment (not including account) - /container/object_name - - - etag: the etag given back when the segment was PUT - - - size_bytes: the size of the segment in bytes - - The format of the list will be: - - json: - [{"path": "/cont/object", - "etag": "etagoftheobjectsegment", - "size_bytes": 1048576}, ...] - - The number of object segments is limited to a configurable amount, default - 1000. Each segment, except for the final one, must be at least 1 megabyte - (configurable). On upload, the middleware will head every segment passed in - and verify the size and etag of each. If any of the objects do not match - (not found, size/etag mismatch, below minimum size) then the user will - receive a 4xx error response. If everything does match, the user will - receive a 2xx response and the SLO object is ready for downloading. - Behind the scenes, on success, a json manifest generated from the user - input is sent to object servers with an extra "X-Static-Large-Object: True" - header and a modified Content-Type. The parameter: swift_bytes=$total_size - will be appended to the existing Content-Type, where total_size is the sum - of all the included segments' size_bytes. This extra parameter will be - hidden from the user. - Manifest files can reference objects in separate containers, which will - improve concurrent upload speed. Objects can be referenced by multiple - manifests. -
-
- Retrieve a large object - A GET request to the manifest object will return the concatenation of the - objects from the manifest much like DLO. If any of the segments from the - manifest are not found or their Etag/Content Length no longer match the - connection will drop. In this case a 409 Conflict will be logged in the - proxy logs and the user will receive incomplete results. - The headers from this GET or HEAD request will return the metadata - attached to the manifest object itself with some exceptions: - - Content-Length: the total size of the SLO (the sum of the - sizes of the segments in the manifest) - - - X-Static-Large-Object: True - - - Etag: the etag of the SLO (generated the same way as - DLO) - - A GET request with the query parameter:: - ?multipart-manifest=get Will return the - actual manifest file itself. This is generated json and does not match the - data sent from the original multipart-manifest=put. Use this call for - debugging. - When the manifest object is uploaded you are more or less guaranteed that - every segment in the manifest exists and matched the specifications. - However, there is nothing that prevents the user from breaking the SLO - download by deleting/replacing a segment referenced in the manifest. It is - left to the user use caution in handling the segments. -
-
- Delete a large object - A DELETE request will just delete the manifest object itself. A DELETE - with a query parameter: - ?multipart-manifest=delete will delete all - the segments referenced in the manifest and then, if successful, the - manifest itself. The failure response will be similar to the bulk delete - middleware. -
-
- Modify a large object - PUTs / POSTs will work as expected, PUTs will just overwrite the manifest - object for example. -
-
- Container listings - In a container listing the size listed for SLO manifest objects will be - the total_size of the concatenated segments in the manifest. The overall - X-Container-Bytes-Used for the container (and subsequently for the account) - will not reflect total_size of the manifest but the actual size of the json - data stored. The reason for this somewhat confusing discrepancy is we want - the container listing to reflect the size of the manifest object when it is - downloaded. We do not, however, want to count the bytes-used twice (for both - the manifest and the segments it's referring to) in the container and - account metadata which can be used for stats purposes. -
-
-
- Container quotas - The container_quotas middleware implements simple quotas that can be imposed - on swift containers by a user with the ability to set container metadata, most - likely the account administrator. This can be useful for limiting the scope of - containers that are delegated to non-admin users, exposed to formpost uploads, - or just as a self-imposed sanity check. - Any object PUT operations that exceed these quotas return a 413 response - (request entity too large) with a descriptive body. - Quotas are subject to several limitations: eventual consistency, the - timeliness of the cached container_info (60 second ttl by default), and it's - unable to reject chunked transfer uploads that exceed the quota (though once the - quota is exceeded, new chunked transfers will be refused). - Quotas are set by adding meta values to the container, and are validated when - set: - - X-Container-Meta-Quota-Bytes: Maximum size of the container, in - bytes. - - - X-Container-Meta-Quota-Count: Maximum object count of the - container. - - -
-
- Account quotas - The account_quotas middleware aims to block write requests (PUT, POST) if a - given account quota (in bytes) is exceeded while DELETE requests are still - allowed. - The x-account-meta-quota-bytes metadata entry must be set to store and enable - the quota. Write requests to this metadata entry are only permitted for - resellers. There isn't any account quota limitation on a reseller account even - if x-account-meta-quota-bytes is set. - Any object PUT operations that exceed the quota return a 413 response (request - entity too large) with a descriptive body. - The following command uses an admin account that own the Reseller role to set - a quota on the test account: - swift -A http://127.0.0.1:8080/auth/v1.0 -U admin:admin -K admin --os-storage-url=http://127.0.0.1:8080/v1/AUTH_test post -m quota-bytes:10000 - Here is the stat listing of an account where quota has been set: - swift -A http://127.0.0.1:8080/auth/v1.0 -U test:tester -K testing stat - Account: AUTH_test - Containers: 0 - Objects: 0 - Bytes: 0 - Meta Quota-Bytes: 10000 - X-Timestamp: 1374075958.37454 - X-Trans-Id: tx602634cf478546a39b1be-0051e6bc7a - - The command below removes the account quota: - swift -A http://127.0.0.1:8080/auth/v1.0 -U admin:admin -K admin --os-storage-url=http://127.0.0.1:8080/v1/AUTH_test post -m quota-bytes: - -
-
-
- Bulk delete - Will delete multiple files from their account with a single request. Responds to - DELETE requests with a header 'X-Bulk-Delete: true_value'. The body of the DELETE - request will be a newline separated list of files to delete. The files listed must - be URL encoded and in the form: - - /container_name/obj_name - - - If all files were successfully deleted (or did not exist) will return an HTTPOk. - If any files failed to delete will return an HTTPBadGateway. In both cases the - response body is a json dictionary specifying in the number of files successfully - deleted, not found, and a list of the files that failed. -
-
- Configure Object Storage with the S3 API - The Swift3 middleware emulates the S3 REST API on top of Object Storage. - The following operations are currently supported: - - - GET Service - - - DELETE Bucket - - - GET Bucket (List Objects) - - - PUT Bucket - - - DELETE Object - - - GET Object - - - HEAD Object - - - PUT Object - - - PUT Object (Copy) - - - To use this middleware, first download the latest version from its repository to - your proxy server(s). - $ git clone https://github.com/fujita/swift3.git - Optional: To use this middleware with Swift 1.7.0 and previous versions, you'll - need to use the v1.7 tag of the fujita/swift3 repository. Clone the repo as above - and then: - $ cd swift3; git checkout v1.7 - Then, install it using standard python mechanisms, such as: - $ sudo python setup.py install - Alternatively, if you have configured the Ubuntu Cloud Archive, you may use: - $ sudo apt-get install swift-python-s3 - To add this middleware to your configuration, add the swift3 middleware in front - of the auth middleware, and before any other middleware that look at swift requests - (like rate limiting). - Ensure that your proxy-server.conf file contains swift3 in the pipeline and the - [filter:swift3] section, as shown below: - -[pipeline:main] -pipeline = healthcheck cache swift3 swauth proxy-server - -[filter:swift3] -use = egg:swift3#swift3 - - Next, configure the tool that you use to connect to the S3 API. For S3curl, for - example, you'll need to add your host IP information by adding y our host IP to the - @endpoints array (line 33 in s3curl.pl): - my @endpoints = ( '1.2.3.4'); - Now you can send commands to the endpoint, such as: - -$ ./s3curl.pl - 'myacc:myuser' -key mypw -get - -s -v http://1.2.3.4:8080 - - To set up your client, the access key will be the concatenation of the account and - user strings that should look like test:tester, and the secret access key is the - account password. The host should also point to the Swift storage node's hostname. - It also will have to use the old-style calling format, and not the hostname-based - container format. Here is an example client setup using the Python boto library on a - locally installed all-in-one Swift installation. - -connection = boto.s3.Connection( - aws_access_key_id='test:tester', - aws_secret_access_key='testing', - port=8080, - host='127.0.0.1', - is_secure=False, - calling_format=boto.s3.connection.OrdinaryCallingFormat()) - -
-
- Manage Object Storage with CLI Swift - In the Object Store (swift) project there is a tool that can perform a variety of - tasks on your storage cluster named swift. This client utility can be used for adhoc - processing, to gather statistics, list items, update metadata, upload, download and - delete files. It is based on the native swift client library client.py. - Incorporating client.py into swift provides many benefits such as seamlessly - re-authorizing if the current token expires in the middle of processing, retrying - operations up to five times and a processing concurrency of 10. All of these things - help make the swift tool robust and great for operational use. -
- Swift ACLs - Swift ACLs work with users and accounts. Users have roles on accounts - such - as '.admin', which allows full access to all containers and objects under the - account. ACLs are set at the container level and support lists for read and - write access, which are set with the X-Container-Read and X-Container-Write - header respectively. - The swift client can be used to set the acls, using the post subcommand with - the option '-r' for the read ACL, and '-w' for the write ACL. This example - allows the user 'testuser' to read objects in the container: - - $ swift post -r 'testuser' - - This could instead be a list of users. - If you are using the StaticWeb middleware to allow OpenStack Object Storage to - serve public web content, you should also be aware of the ACL syntax for - managing allowed referrers. The syntax is '.r:' followed by a list of allowed - referrers. For example, this command allows all referring domains access to the - object: - - $ swift post -r '.r:*' - - -
-
- Swift CLI Basics - The command line usage for swift, the CLI tool is: - swift (command) [options] [args] - Here are the available commands for swift. - - stat [container] [object] - Displays information for the account, container, or object depending on - the args given (if any). - - - list [options] [container] - Lists the containers for the account or the objects for a container. -p or - -prefix is an option that will only list items beginning with that prefix. - -d or -delimiter is option (for container listings only) that will roll up - items with the given delimiter, or character that can act as a nested - directory organizer. - - - upload [options] container file_or_directory [file_or_directory] - […] - Uploads to the given container the files and directories specified by the - remaining args. -c or -changed is an option that will only upload files that - have changed since the last upload. - - - post [options] [container] [object] - Updates meta information for the account, container, or object depending - on the args given. If the container is not found, it will be created - automatically; but this is not true for accounts and objects. Containers - also allow the -r (or -read-acl) and -w (or -write-acl) options. The -m or - -meta option is allowed on all and used to define the user meta data items - to set in the form Name:Value. This option can be repeated. - Example: post -m Color:Blue -m Size:Large - - - download —all OR download container [object] [object] … - Downloads everything in the account (with —all), or everything in a - container, or a list of objects depending on the args given. For a single - object download, you may use the -o [—output] (filename) option to redirect - the output to a specific file or if “-” then just redirect to stdout. - - - delete —all OR delete container [object] [object] … - Deletes everything in the account (with —all), or everything in a - container, or a list of objects depending on the args given. - Example: swift -A https://auth.api.rackspacecloud.com/v1.0 -U user -K key - stat - - - Options for swift - -version show program’s version number and exit - -h, -help show this help message and exit - -s, -snet Use SERVICENET internal network - -v, -verbose Print more info - -q, -quiet Suppress status output - -A AUTH, -auth=AUTH URL for obtaining an auth token - -U USER, -user=USER User name for obtaining an auth token - -K KEY, -key=KEY Key for obtaining an auth token - -
-
- Analyze log files with Swift CLI - When you want quick, command-line answers to questions about logs, you can use - swift with the -o or -output option. The -o —output option can only be used with - a single object download to redirect the data stream to either a different file - name or to STDOUT (-). The ability to redirect the output to STDOUT allows you - to pipe “|” data without saving it to disk first. One common use case is being - able to do some quick log file analysis. First let’s use swift to setup some - data for the examples. The “logtest” directory contains four log files with the - following line format. - - Files: - 2010-11-16-21_access.log - 2010-11-16-22_access.log - 2010-11-15-21_access.log - 2010-11-15-22_access.log - - Log lines: - Nov 15 21:53:52 lucid64 proxy-server - 127.0.0.1 15/Nov/2010/22/53/52 DELETE /v1/AUTH_cd4f57824deb4248a533f2c28bf156d3/2eefc05599d44df38a7f18b0b42ffedd HTTP/1.0 204 - \ -- test%3Atester%2CAUTH_tkcdab3c6296e249d7b7e2454ee57266ff - - - txaba5984c-aac7-460e-b04b-afc43f0c6571 - 0.0432 - - - The swift tool can easily upload the four log files into a container named - “logtest”: - -$ cd logs -$ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing upload logtest *.log - - -2010-11-16-21_access.log -2010-11-16-22_access.log -2010-11-15-21_access.log -2010-11-15-22_access.log - - Get statistics on the account: $ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing -q stat - -Account: AUTH_cd4f57824deb4248a533f2c28bf156d3 -Containers: 1 -Objects: 4 -Bytes: 5888268 - - Get statistics on the container: - $ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing stat logtest Account: AUTH_cd4f57824deb4248a533f2c28bf156d3 -Container: logtest -Objects: 4 -Bytes: 5864468 -Read ACL: -Write ACL: - - List all the objects in the container: - $ swift -A http:///swift-auth.com:11000/v1.0 -U test:tester -K testing list logtest2010-11-15-21_access.log -2010-11-15-22_access.log -2010-11-16-21_access.log -2010-11-16-22_access.log - - The following examples use the -o —output option with (-) to help answer - questions about the uploaded log files. The swift command will download an - object, stream it to awk to determine the breakdown of requests by return code - for everything during 2200 on November 16th, 2010. Based on the log line format - column 9 is the type of request and column 12 is the return code. After awk - processes the data stream it is piped to sort and then uniq -c to sum up the - number of occurrences for each combination of request type and return - code. - - -$ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing download -o - logtest 2010-11-16-22_access.log | awk ‘{ print $9”-“$12}’ | sort | uniq -c - - 805 DELETE-204 -12 DELETE-404 -2 DELETE-409 -723 GET-200 -142 GET-204 -74 GET-206 -80 GET-304 -34 GET-401 -5 GET-403 -18 GET-404 -166 GET-412 -2 GET-416 -50 HEAD-200 -17 HEAD-204 -20 HEAD-401 -8 HEAD-404 -30 POST-202 -25 POST-204 -22 POST-400 -6 POST-404 -842 PUT-201 -2 PUT-202 -32 PUT-400 -4 PUT-403 -4 PUT-404 -2 PUT-411 -6 PUT-412 -6 PUT-413 -2 PUT-422 -8 PUT-499 - - This example uses a bash for loop with awk, swift with its -o —output option - with a hyphen (-) to find out how many PUT requests are in each log file. First - create a list of objects by running swift with the list command on the “logtest” - container; then for each item in the list run swift with download -o - then pipe - the output into grep to filter the put requests and finally into wc -l to count - the lines. - - $ for f in `swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing list logtest` ; \ - do echo -ne “PUTS - ” ; swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing download -o - logtest $f | grep PUT | wc -l ; \ - done - -2010-11-15-21_access.log - PUTS - 402 -2010-11-15-22_access.log - PUTS - 1091 -2010-11-16-21_access.log - PUTS - 892 -2010-11-16-22_access.log - PUTS - 910 - - - By adding the -p —prefix option a prefix query is performed on the list to - return only the object names that begin with a specific string. Let’s determine - out how many PUT requests are in each object with a name beginning with - “2010-11-15”. First create a list of objects by running swift with the list - command on the “logtest” container with the prefix option -p 2010-11-15. Then on - each of item(s) returned run swift with the download -o - then pipe the output - to grep and wc as in the previous example. The echo command is added to display - the object name. - - $ for f in `swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing list -p 2010-11-15 logtest` ; \ - do echo -ne “$f - PUTS - ” ; swift -A http://127.0.0.1:11000/v1.0 -U test:tester -K testing download -o - logtest $f | grep PUT | wc -l ; \ - done - 2010-11-15-21_access.log - PUTS - 402 -2010-11-15-22_access.log - PUTS - 910 - - The swift utility is simple, scalable, flexible and provides useful solutions - all of which are core principles of cloud computing; with the -o output option - being just one of its many features. -
-
-
-
- Object Storage tutorials - We want people to use OpenStack for practical problem solving, and the increasing size and - density of web content makes for a great use-case for object storage. These tutorials show - you how to use your OpenStack Object Storage installation for practical purposes, and it - assumes Object Storage is already installed. -
- Store large photos or videos in the cloud - In this OpenStack tutorial, we’ll walk through using an Object Storage installation to - back up all your photos or videos. As the sensors on consumer-grade and pro-sumer grade - cameras generate more and more megapixels, we all need a place to back our files to and - know they are safe. - We'll go through this tutorial in parts: - - - Setting up secure access to Object Storage. - Configuring Cyberduck for connecting to OpenStack Object Storage. - Copying files to the cloud. - -
- Part I: Set up secure access - In this part, we'll get the proxy server running with SSL on the Object Storage - installation. It's a requirement for using Cyberduck as a client interface to Object - Storage. - You will need a key and certificate to do this, which we can create as a - self-signed for the tutorial since we can do the extra steps to have Cyberduck - accept it. Creating a self-signed cert can usually be done with these commands on - the proxy server: - $ cd /etc/swift -$ openssl req -new -x509 -nodes -out cert.crt -keyout cert.key - - Ensure these generated files are in /etc/swift/cert.crt and /etc/swift/cert.key. - You also should configure your iptables to enable https traffic. Here's an example - setup that works. - Chain INPUT (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination -76774 1543M ACCEPT all -- lo any localhost anywhere - 416K 537M ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED - 106 6682 ACCEPT tcp -- any any anywhere anywhere tcp dpt:https - 13 760 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh - 3 124 ACCEPT icmp -- any any anywhere anywhere icmp echo-request - 782 38880 DROP all -- any any anywhere anywhere - -Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination - 0 0 DROP all -- any any anywhere anywhere - -Chain OUTPUT (policy ACCEPT 397K packets, 1561M bytes) - pkts bytes target prot opt in out source destination - If you don't have access to the Object Storage installation to configure these - settings, ask your service provider to set up secure access for you.Then, edit your proxy-server.conf file to - include the following in the [DEFAULT] sections. - -[DEFAULT] -bind_port = 443 -cert_file = /etc/swift/cert.crt -key_file = /etc/swift/cert.key - - Also, make sure you use https: for all references to the URL for the server in the - .conf files as needed. - Verify that you can connect using the Public URL to Object Storage by using the - "swift" tool: - - $ swift -A https://yourswiftinstall.com:11000/v1.0 -U test:tester -K testing stat - - - Okay, you've created the access that Cyberduck expects for your Object Storage - installation. Let's start configuring the Cyberduck side of things. - -
-
- - Part II: Configure Cyberduck - - - See the Cyberduck website - for further details. - - - - After installing Cyberduck you'll need to change the path/context - used for the authentication URL. The default value shipped with - Cyberduck is incorrect. - - - On OS X open a Terminal window and execute, - $ defaults write ch.sudo.cyberduck cf.authentication.context /auth/v1.0 - - On Windows open the preferences file in a text - editor. The exact location of this file is described - here. If this path doesn't exist you may - need to start and stop Cyberduck to have it generate - the config file. Once you've opened the file add the - setting, - <setting name="cf.authentication.context" value="/auth/v1.0" /> - - - To connect to Swift start Cyberduck and click the - Open Connection toolbar button or choose - File > Open Connection. Select - Swift (OpenStack Object Storage) in the - dropdown and enter your cluster details. - - - Server - - your proxy server's hostname or IP address - - - - Port - 443 - - - Username - - - account name followed by a colon and then the user name, - for example test:tester - - - - - Password - - - password for the account and user name entered above - - - - -
- Example Cyberduck Swift Connection - - - - - -
-
- - - Connecting to an unsecured Swift cluster - An Unsecured Swift Cluster does not use https - connections. Download the Unsecured Swift profile file and - double click it to import it into Cyberduck. - - When creating a new connection select Swift (HTTP). - Enter your connection details as described above. You'll need - to change the port since presumably you won't want to use 443. - - -
-
- Part III: Create containers (folders) and upload files - Now you want to create containers to hold your files. Without containers, Object - Storage doesn't know where to put the files. In the Action menu, choose New Folder - and name the folder. - Next you can drag and drop files into the created folder or select File > Upload - to select files to upload to the OpenStack Object Storage service.
- Example Cyberduck Swift Showing Uploads - - - - - -
Et voila! You can back up terabytes of data if you just have the space and the data. That's a lot of pictures or video, so get snapping and rolling! -
-
-
-
- Object Storage monitoring - - Excerpted from a blog post by Darrell Bishop - An OpenStack Object Storage cluster is a complicated beast—a - collection of many daemons across many nodes, all working - together. With so many “moving parts” it’s important to be - able to tell what’s going on inside the cluster. Tracking - server-level metrics like CPU utilization, load, memory - consumption, disk usage and utilization, etc. is necessary, - but not sufficient. We need to know what the different daemons - are doing on each server. What’s the volume of object - replication on node8? How long is it taking? Are there errors? - If so, when did they happen? - In such a complex ecosystem, it’s no surprise that there are - multiple approaches to getting the answers to these kinds of - questions. Let’s examine some of the existing approaches to - OpenStack Object Storage monitoring. -
- Swift Recon - The Swift Recon middleware can provide general - machine stats (load average, socket stats, - /proc/meminfo contents, etc.) as well as - Swift-specific metrics: - - - The MD5 sum of each ring file. - - - The most recent object replication time. - - - Count of each type of quarantined file: account, - container, or object. - - - Count of “async_pendings” (deferred container - updates) on disk. - - - Swift Recon is middleware installed in the object - server’s pipeline and takes one required option: a local - cache directory. Tracking of async_pendings requires an - additional cron job per object server. Data is then - accessed by sending HTTP requests to the object server - directly, or by using the swift-recon command-line - tool. - There are some good Object Storage cluster stats in - there, but the general server metrics overlap with - existing server monitoring systems and to get the - Swift-specific metrics into a monitoring system, they must - be polled. Swift Recon is essentially acting as a - middle-man metrics collector. The process actually feeding - metrics to your stats system, like collectd, gmond, etc., - is probably already running on the storage node. So it - could either talk to Swift Recon or just collect the - metrics itself. - There’s an upcoming update to Swift Recon which broadens - support to the account and container servers. The - auditors, replicators, and updaters can also report - statistics, but only for the most recent run. -
-
- Swift-Informant - Florian Hines developed the Swift-Informant middleware to get real-time - visibility into Object Storage client requests. It sits in - the proxy server’s pipeline and after each request to the - proxy server, sends three metrics to a StatsD server: - - A counter increment for a metric like obj.GET.200 or - cont.PUT.404. - Timing data for a metric like acct.GET.200 or obj.GET.200. [The README says the metrics will look - like duration.acct.GET.200, but I don’t see - the “duration” in the code. I’m not sure what Etsy’s server does, but our StatsD - server turns timing metrics into 5 derivative metrics with new segments - appended, so it probably works as coded. The first metric above would turn into - acct.GET.200.lower, acct.GET.200.upper, acct.GET.200.mean, acct.GET.200.upper_90, and acct.GET.200.count] - A counter increase by the bytes transferred for a metric like tfer.obj.PUT.201. - - This is good for getting a feel for the quality of - service clients are experiencing with the timing metrics, - as well as getting a feel for the volume of the various - permutations of request server type, command, and response - code. Swift-Informant also requires no change to core - Object Storage code since it is implemented as middleware. - However, because of this, it gives you no insight into the - workings of the cluster past the proxy server. If one - storage node’s responsiveness degrades for some reason, - you’ll only see that some of your requests are bad—either - as high latency or error status codes. You won’t know - exactly why or where that request tried to go. Maybe the - container server in question was on a good node, but the - object server was on a different, poorly-performing - node. -
-
- Statsdlog - Florian’s Statsdlog project increments StatsD counters - based on logged events. Like Swift-Informant, it is also - non-intrusive, but statsdlog can track events from all - Object Storage daemons, not just proxy-server. The daemon - listens to a UDP stream of syslog messages and StatsD - counters are incremented when a log line matches a regular - expression. Metric names are mapped to regex match - patterns in a JSON file, allowing flexible configuration - of what metrics are extracted from the log stream. - Currently, only the first matching regex triggers a - StatsD counter increment, and the counter is always - incremented by 1. There’s no way to increment a counter by - more than one or send timing data to StatsD based on the - log line content. The tool could be extended to handle - more metrics per line and data extraction, including - timing data. But even then, there would still be a - coupling between the log textual format and the log - parsing regexes, which would themselves be more complex in - order to support multiple matches per line and data - extraction. Also, log processing introduces a delay - between the triggering event and sending the data to - StatsD. We would prefer to increment error counters where - they occur, send timing data as soon as it is known, avoid - coupling between a log string and a parsing regex, and not - introduce a time delay between events and sending data to - StatsD. And that brings us to the next method of gathering - Object Storage operational metrics. -
-
- Swift StatsD logging - StatsD was designed for application code to be deeply instrumented; metrics are sent in real-time by the code which just noticed something or did something. The overhead of sending a metric is extremely low: a sendto of one UDP packet. If that overhead is still too high, the StatsD client library can send only a random portion of samples and StatsD will approximate the actual number when flushing metrics upstream. - To avoid the problems inherent with middleware-based - monitoring and after-the-fact log processing, the sending - of StatsD metrics is integrated into Object Storage - itself. The submitted change set currently reports 124 - metrics across 15 Object Storage daemons and the tempauth - middleware. Details of the metrics tracked are in the - Swift Administration Guide. - The sending of metrics is integrated with the logging framework. To enable, configure log_statsd_host in the relevant config file. You can also specify the port and a default sample rate. The specified default sample rate is used unless a specific call to a statsd logging method (see the list below) overrides it. Currently, no logging calls override the sample rate, but it’s conceivable that some metrics may require accuracy (sample_rate == 1) while others may not. - [DEFAULT] - ... -log_statsd_host = 127.0.0.1 -log_statsd_port = 8125 -log_statsd_default_sample_rate = 1 - Then the LogAdapter object returned by get_logger(), usually stored in self.logger, has the following new methods: - - set_statsd_prefix(self, prefix) Sets the client library’s stat prefix value which gets prepended to every metric. The default prefix is the “name” of the logger (eg. “object-server”, “container-auditor”, etc.). This is currently used to turn “proxy-server” into one of “proxy-server.Account”, “proxy-server.Container”, or “proxy-server.Object” as soon as the Controller object is determined and instantiated for the request. - update_stats(self, metric, amount, sample_rate=1) Increments the supplied metric by the given amount. This is used when you need to add or subtract more that one from a counter, like incrementing “suffix.hashes” by the number of computed hashes in the object replicator. - increment(self, metric, sample_rate=1) Increments the given counter metric by one. - decrement(self, metric, sample_rate=1) Lowers the given counter metric by one. - timing(self, metric, timing_ms, sample_rate=1) Record that the given metric took the supplied number of milliseconds. - timing_since(self, metric, orig_time, sample_rate=1) Convenience method to record a timing metric whose value is “now” minus an existing timestamp. - - Note that these logging methods may safely be called - anywhere you have a logger object. If StatsD logging has - not been configured, the methods are no-ops. This avoids - messy conditional logic each place a metric is recorded. - Here’s two example usages of the new logging - methods: - # swift/obj/replicator.py -def update(self, job): - # ... - begin = time.time() - try: - hashed, local_hash = tpool.execute(tpooled_get_hashes, job['path'], - do_listdir=(self.replication_count % 10) == 0, - reclaim_age=self.reclaim_age) - # See tpooled_get_hashes "Hack". - if isinstance(hashed, BaseException): - raise hashed - self.suffix_hash += hashed - self.logger.update_stats('suffix.hashes', hashed) - # ... - finally: - self.partition_times.append(time.time() - begin) - self.logger.timing_since('partition.update.timing', begin) - # swift/container/updater.py -def process_container(self, dbfile): - # ... - start_time = time.time() - # ... - for event in events: - if 200 <= event.wait() < 300: - successes += 1 - else: - failures += 1 - if successes > failures: - self.logger.increment('successes') - # ... - else: - self.logger.increment('failures') - # ... - # Only track timing data for attempted updates: - self.logger.timing_since('timing', start_time) - else: - self.logger.increment('no_changes') - self.no_changes += 1 - The development team of StatsD wanted to use the pystatsd client library (not to be confused - with a similar-looking project also hosted on - GitHub), but the released version on PyPi was missing two - desired features the latest version in GitHub had: the - ability to configure a metrics prefix in the client object - and a convenience method for sending timing data between - “now” and a “start” timestamp you already have. So they - just implemented a simple StatsD client library from - scratch with the same interface. This has the nice fringe - benefit of not introducing another external library - dependency into Object Storage. -
-
-
- Troubleshoot Object Storage - For Object Storage, everything is logged in /var/log/syslog (or messages on some distros). Several settings enable further customization of logging, such as log_name, log_facility, and log_level, within the object server configuration files. -
- Handle drive failure - In the event that a drive has failed, the first step is to make sure the drive is unmounted. This will make it easier for OpenStack Object Storage to work around the failure until it has been resolved. If the drive is going to be replaced immediately, then it is just best to replace the drive, format it, remount it, and let replication fill it up. - If the drive can’t be replaced immediately, then it is best to leave it unmounted, and remove the drive from the ring. This will allow all the replicas that were on that drive to be replicated elsewhere until the drive is replaced. Once the drive is replaced, it can be re-added to the ring. - Rackspace has seen hints at drive failures by looking at error messages in /var/log/kern.log - - do consider checking this in your monitoring -
-
- Handle server failure - If a server is having hardware issues, it is a good idea to make sure the OpenStack Object Storage services are not running. This will allow OpenStack Object Storage to work around the failure while you troubleshoot. - If the server just needs a reboot, or a small amount of work that should only last a couple of hours, then it is probably best to let OpenStack Object Storage work around the failure and get the machine fixed and back online. When the machine comes back online, replication will make sure that anything that is missing during the downtime will get updated. - If the server has more serious issues, then it is probably best to remove all of the server’s devices from the ring. Once the server has been repaired and is back online, the server’s devices can be added back into the ring. It is important that the devices are reformatted before putting them back into the ring as it is likely to be responsible for a different set of partitions than before. -
-
- Detect failed drives - It has been our experience that when a drive is about to fail, error messages will spew into /var/log/kern.log. There is a script called swift-drive-audit that can be run via cron to watch for bad drives. If errors are detected, it will unmount the bad drive, so that OpenStack Object Storage can work around it. The script takes a configuration file with the following settings: - - - This script has only been tested on Ubuntu 10.04, so if you are using a different distro or OS, some care should be taken before using in production. -
-
- Emergency recovery of ring-builder files - You should always keep a backup of Swift ring builder files. - However, if an emergency occurs, this procedure may assist in returning - your cluster to an operational state. - Using existing Swift tools, there is no way to recover a builder - file from a ring.gz file. However, if you have a knowledge of Python, - it is possible to construct a builder file that is pretty close to - the one you have lost. The following is what you will need to do. - Warning - This procedure is a last-resort for emergency circumstances—it - requires knowledge of the swift python code and may not succeed. - First, load the ring and a new ring-builder object in a Python REPL: - >>> from swift.common.ring import RingData, RingBuilder ->>> ring = RingData.load('/path/to/account.ring.gz') - Now, start copying the data we have in the ring into the builder. - >>> import math ->>> partitions = len(ring._replica2part2dev_id[0]) ->>> replicas = len(ring._replica2part2dev_id) - ->>> builder = RingBuilder(int(Math.log(partitions, 2)), replicas, 1) ->>> builder.devs = ring.devs ->>> builder._replica2part2dev = ring.replica2part2dev_id ->>> builder._last_part_moves_epoch = 0 ->>> builder._last_part_moves = array('B', (0 for _ in xrange(self.parts))) ->>> builder._set_parts_wanted() ->>> for d in builder._iter_devs(): - d['parts'] = 0 ->>> for p2d in builder._replica2part2dev: - for dev_id in p2d: - builder.devs[dev_id]['parts'] += 1 - This is the extent of the recoverable fields. For - min_part_hours you'll either have to remember - what the value you used was, or just make up a new one. - >>> builder.change_min_part_hours(24) # or whatever you want it to be - Try some validation: if this doesn't raise an exception, you may - feel some hope. Not too much, though. - >>> builder.validate() - Save the builder. - >>> import pickle ->>> pickle.dump(builder.to_dict(), open('account.builder', 'wb'), protocol=2) - You should now have a file called 'account.builder' in the current - working directory. - Next, run swift-ring-builder account.builder write_ring - and compare the new account.ring.gz to the account.ring.gz that you started - from. They probably won't be byte-for-byte identical, but if you load them - up in a REPL and their _replica2part2dev_id and - devs attributes are the same (or nearly so), then you're - in good shape. - Next, repeat the procedure for container.ring.gz - and object.ring.gz, and you might get usable builder - files. -
-
+ +
diff --git a/doc/src/docbkx/admin-guide-cloud/section_object-storage-admin.xml b/doc/src/docbkx/admin-guide-cloud/section_object-storage-admin.xml new file mode 100644 index 0000000000..b412925f8f --- /dev/null +++ b/doc/src/docbkx/admin-guide-cloud/section_object-storage-admin.xml @@ -0,0 +1,17 @@ + +
+ System Administration for OpenStack Object Storage + By understanding the concepts inherent to the Object Storage + system you can better monitor and administer your storage + solution. The majority of the administration information is maintained + in developer documentation at + docs.openstack.org/developer/swift/. + Refer to the OpenStack Configuration Reference + for a listing of all configuration options for OpenStack Object + Storage. +
\ No newline at end of file diff --git a/doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml b/doc/src/docbkx/admin-guide-cloud/section_object-storage-monitoring.xml similarity index 98% rename from doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml rename to doc/src/docbkx/admin-guide-cloud/section_object-storage-monitoring.xml index a03d5abdb3..39d90b30d8 100644 --- a/doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml +++ b/doc/src/docbkx/admin-guide-cloud/section_object-storage-monitoring.xml @@ -1,7 +1,9 @@ - + xmlns:xlink="http://www.w3.org/1999/xlink" + version="5.0" + xml:id="ch_introduction-to-openstack-object-storage-monitoring"> OpenStack Object Storage Monitoring Excerpted from a blog post by - - + diff --git a/doc/src/docbkx/common/section_about-object-storage.xml b/doc/src/docbkx/common/section_about-object-storage.xml new file mode 100644 index 0000000000..0ee0a8689e --- /dev/null +++ b/doc/src/docbkx/common/section_about-object-storage.xml @@ -0,0 +1,13 @@ + +
+ Introduction to OpenStack Object Storage + OpenStack Object Storage is a scalable object storage system - it is not a file system in the + traditional sense. You will not be able to mount this system like traditional SAN or NAS volumes. + Since OpenStack Object Storage is a different way of thinking when it comes to storage, take a few + moments to review the key concepts in the developer documentation at + docs.openstack.org/developer/swift/. +
diff --git a/doc/src/docbkx/openstack-config/ch_objectstorageconfigure.xml b/doc/src/docbkx/openstack-config/ch_objectstorageconfigure.xml index e99aaa0574..e75687cb12 100644 --- a/doc/src/docbkx/openstack-config/ch_objectstorageconfigure.xml +++ b/doc/src/docbkx/openstack-config/ch_objectstorageconfigure.xml @@ -8,26 +8,8 @@ background daemons, and paste.deploy to manage server configurations. Default configuration options are set in the [DEFAULT] section, and any options specified there can be overridden in any of the other sections. + -
Object Server Configuration An example Object Server configuration can be found at diff --git a/doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml b/doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml deleted file mode 100644 index af12188226..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - Introduction to OpenStack Object Storage - OpenStack Object Storage is a scalable object storage system - it is not a file system in - the traditional sense. You will not be able to mount this system like traditional SAN or NAS - volumes. Since OpenStack Object Storage is a different way of thinking when it comes to - storage, take a few moments to review the key concepts listed below. -
- Accounts and Account Servers - The OpenStack Object Storage system is designed to be used by many different storage - consumers or customers. Each user must identify themselves using an authentication - system. - Nodes that run the Account service are a separate concept from individual accounts. - Account servers are part of the storage system and must be configured along with - Container servers and Object servers. -
-
- Authentication and Access Permissions - You must authenticate against an Authentication service to receive OpenStack Object - Storage connection parameters and an authentication token. The token must be passed in - for all subsequent container/object operations. One authentication service that you can - use as a middleware example is called swauth and you can download it from - https://github.com/gholt/swauth. You can also integrate with the OpenStack Identity Service, code-named Keystone, which you can download from https://github.com/openstack/keystone. - - Typically the language-specific APIs handle authentication, token passing, and HTTPS - request/response communication. - - - You can implement access control for objects either for users or accounts using - X-Container-Read: accountname and X-Container-Write: accountname:username, which allows - any user from the accountname account to read but only allows the username user from the - accountname account to write. You can also grant public access to objects stored in - OpenStack Object Storage but also limit public access using the Referer header to - prevent site-based content theft such as hot-linking (for example, linking to an image - file from off-site and therefore using other's bandwidth). The public container settings - are used as the default authorization over access control lists. For example, using - X-Container-Read: referer:any allows anyone to read from the container regardless of - other authorization settings. - Generally speaking, each user has their own storage account and has full access to - that account. Users must authenticate with their credentials as described above, but - once authenticated they can create/delete containers and objects within that account. - The only way a user can access the content from another account is if they share an API - access key or a session token provided by your authentication system. -
-
- Containers and Objects - A container is a storage compartment for your data and provides a way for you to - organize your data. You can think of a container as a folder in Windows® or a directory in - UNIX®. The primary difference between a container and these other file system concepts is - that containers cannot be nested. You can, however, create an unlimited number of containers - within your account. Data must be stored in a container so you must have at least one - container defined in your account prior to uploading data. - The only restrictions on container names is that they cannot contain a forward slash - (/) or an ascii null (%00) and must be less than 257 bytes in length. - Please note that the length - restriction applies to the name after it has been URL encoded. For example, a container name - of Course Docs would be URL encoded as Course%20Docs and therefore - be 13 bytes in length rather than the expected 11. - - An object is the basic storage entity and any optional metadata that represents the - files you store in the OpenStack Object Storage system. When you upload data to OpenStack Object Storage, the data is - stored as-is (no compression or encryption) and consists of a location (container), the - object's name, and any metadata consisting of key/value pairs. For instance, you may chose - to store a backup of your digital photos and organize them into albums. In this case, each - object could be tagged with metadata such as Album : Caribbean Cruise or - Album : Aspen Ski Trip. - The only restriction on object names is that they must be less than 1024 bytes in length - after URL encoding. For example, an object name of C++final(v2).txt should be - URL encoded as C%2B%2Bfinal%28v2%29.txt and therefore be 24 bytes in length - rather than the expected 16. - The maximum allowable size for a storage object upon upload is 5 gigabytes (GB) and - the minimum is zero bytes. You can use the built-in large object support and the swift - utility to retrieve objects larger than 5 GB. - For metadata, you should not exceed 90 individual key/value pairs for any one object - and the total byte length of all key/value pairs should not exceed 4KB (4096 bytes). - WarningThe Object Storage API uses HTTP which specifies that header - fields, such as those used to send metadata are case insensitive. Please do not expect - the case of metadata items being preserved. -
-
- Operations - Operations are the actions you perform within an OpenStack Object Storage system such - as creating or deleting containers, uploading or downloading objects, and so on. The - full list of operations is documented in the Developer Guide. Operations may be - performed via the REST web service API or a language-specific API; currently, we support - Python, PHP, Java, Ruby, and C#/.NET. - - All operations must include a valid authorization token from your authorization system. - -
- -
- Language-Specific API Bindings - A set of supported API bindings in several popular languages are available from the - Rackspace Cloud Files product, which uses OpenStack Object Storage code for its - implementation. These bindings provide a layer of abstraction on top of the base REST - API, allowing programmers to work with a container and object model instead of working - directly with HTTP requests and responses. These bindings are free (as in beer and as in - speech) to download, use, and modify. They are all licensed under the MIT License as - described in the COPYING file packaged with each binding. If you do make any - improvements to an API, you are encouraged (but not required) to submit those changes - back to us. - The API bindings for Rackspace Cloud Files are hosted at http://github.com/rackspace. Feel - free to coordinate your changes through github or, if you prefer, send your changes to - cloudfiles@rackspacecloud.com. Just make sure to indicate which language and version you - modified and send a unified diff. - Each binding includes its own documentation (either HTML, PDF, or CHM). They also - include code snippets and examples to help you get started. The currently supported API - binding for OpenStack Object Storage are: - - - PHP (requires 5.x and the modules: cURL, FileInfo, mbstring) - - - Python (requires 2.4 or newer) - - - Java (requires JRE v1.5 or newer) - - - C#/.NET (requires .NET Framework v3.5) - - - Ruby (requires 1.8 or newer and mime-tools module) - - - There are no other supported language-specific bindings at this time. You are welcome - to create your own language API bindings and we can help answer any questions during - development, host your code if you like, and give you full credit for your work. -
-
diff --git a/doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml b/doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml deleted file mode 100644 index 9435955e42..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - OpenStack Object Storage Administration Guide - - OpenStack Object Storage Administration - Guide - - - - - - - - OpenStack Foundation - - - - 2010 - 2011 - 2012 - 2013 - OpenStack Foundation - - Grizzly, 2013.1 with Object Storage - 1.8.0 - OpenStack Object Storage - - - - Copyright details are filled in by the - template. - - - - OpenStack™ Object Storage offers open source - software for cloud-based object storage for any - organization. This manual provides guidance for - installing, managing, and understanding the software - that runs OpenStack Object Storage. - - - - - 2013-05-09 - - Updated the book title for - consistency. - - - - 2013-04-30 - - Grizzly release. - - - - 2012-12-06 - - - - Bug fixes and cleanup. Fix bug 1034144 - Add section about cluster - health. - Add a note about the apt-get install - for swift3 from Ubuntu Cloud - Archive. - - - - - - 2012-11-09 - - - - Folsom release of this - document. - - - - - - 2012-08-21 - - - - Add note to the [filter:cache] - section of the proxy-server.conf file - reference indicating that the - memcache_servers value is ignored if - it is specified in - /etc/swift/memcache.conf. - - - Update Cyberduck tutorial. - - - - - - 2012-06-05 - - - - Fix bug 1009170. - - - - - - 2012-05-03 - - - - Begin trunk designation. - - - - - - 2012-05-02 - - - - Essex release. - - - - - - 2012-04-27 - - - - Adds ring copy example. - - - - - - 2012-01-01 - - - - Formatting updates. - - - - - - - - - - - - - - - - diff --git a/doc/src/docbkx/openstack-object-storage-admin/figures/cyberduck_swift_connection.png b/doc/src/docbkx/openstack-object-storage-admin/figures/cyberduck_swift_connection.png deleted file mode 100644 index abd6f3d450a8a5c41e40c204f0b003a7623b6060..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59927 zcmYhib95#_*X|wLwlSI5*2GRGwr$(CZQHhO+s+-^IrBX4dB5}hQET<;s;=6-uiaf$ zYyT=-URDeq1_uTR2nb$6T=*{#5b)H$5&{MB@6Iz;eH0K745qn|ki3MD5Rtrtt%xCz%?Y zpOH=mQQvetHU>feP%J2zI53kQ2rV0B^3C4qDg5{RPArHSr@NeQ`wG9!#|`w|S(*|8 zP#j@KOoZ$)S)mt(u_1zPT*y7#L}0qPSJFOR(mBW@xWcur$@Op8R8EWJ-Retd7&{Ok zVjzLMx^)mbAS14hnW;Uyc`hTxBzX7vJD#LMg_gsi`g!phF?D)Q_emzif-3ZZ;ivk?m7q2+1~5g=3nYST=PBSNIx2imS6%baDFjXvK>T*%>*W#dce?O zAY5_45d!FDz}`)XCw&lgbJrdqx=3IH{SA3XfmZ& z{b?cjNIV>0KVrJ4x|g{JdqWioC=jwQu*xe^M3Bd!;!O%oYE}BJ95_)RD!*6;SvI{? zxm3CoOTvN-ii{X<7QaoBOoC4`NKz{tUT{%>P>?Cy8lDo7gWOHcMJbB5h~$W37lc*~5gdF7Bx$(95XUr@u~*99IET21 z_zn7H3RapYK@Hgqa(vQk`fWO1k}vfTszZ{*UykA>iYMVTqAFr5x@?NiZI{mLoSYq5 z(RgBXy4Ouxr0!}uVtfKVonF~qy`KRA1p%2Ly7^lB6$4o$Lh;3Ed1?i2680+LB}S!a zwMqp}>gV8!3Fm#%1}TiSjHk)R$=k_`$(BiwNtntk$^ps_N*l^KWeG~O%7)5PN}kH6 z%SlUKOD<*26}*2bD>N%c%L$cl6o2ya%aJSUS~4z~ zPU&52%dF9iyf*KBQ6?vbEwfdtmzC|o?R{O-UMqj5Nfrtw45kun&P~WS8$!EbhreBJLvwgP~m1_YHBwP-(&CP@FuwTY*98# zTWQUAD-`Q85}9;17~4}jUKA*}*f{GbZ^2iSHOBP9?!w9<(~emjVx07a>ht9Djf^df z!;FjdE%n3o%vze)`qx%j-dg5cT3w1>BA)=Tm!OLv#PFW*=x`~Ce2J^^prf&)2Oel0 zlA8^TVOn*~kk^h+o*sr_u4D0uu0E-`IGAD^=_|>?LW4YhZR)Si$8fmLsEMf9bmDZ= zhM`6`^)F55mg`-v?rG;uxlP7R&P`9(UpH%wh6bgBGa1@*HD%h}oyxAK*Etg|lQtVd z8;NbFt9XN12U)J3LN6|-zmH5#WqnScwJmeRbBJuMa;JMPZWwn*efjHljeOs}ZQthK zT4CW}C1HEe9AIpJ^d5!Q5v3pv5aH0$G4c7sxW~9TJjTA|73E1s9?eB!-5oSD}ycAL`7Hf1aGYdXic(Di~| ztZgvvVy{wN!rb6+-MII(ZkBv((L?mI=*aiTyDQuq%#$w^Z%Ij|wrcB~?Y~TE@9U&r zZf|k>uwGt#S$?lV)Oc$5x(_~$Ec1o-OtM?s>a-bq13s-MH?v)*Zk!%7pK?EzFIOEw zPeAcqX|G-2HQ-$ktMNNntoXf-a~`^JUwE%~vDMj`Sa5jW^{fWdZUr9$(?cZ?b@?aU znmBU4us%3`!q*ZPO7GEGxvPw&6UziTU0HEL(R``-(F`K){{n)jX-G6!0jY;kwfdjQ(E znr`oWZ(j$YpRr7YnSAO#7aw@qJ=0g|pPT7TU0k6lDufvpAP*94a&`#1>6tYS9 z@iKL>nUoR#wcwJ_-O24Zlg?~vdYZ}1+zI%1B|9F2&n+)6?^jSjva6z{1;^foVMn{C z(bw!}=`S=7f{ctD78UhqU0+`x1`}1J;5JiTRCFZY6t8Kr3Q_~E1^b`oK(V8Rdgd=f z!@o$%z{P4;D+wqLwGbDp8UMF|U73a-ka<7T@86RBiq8r-U{bIJp%wL84xRsZ zz`lG--~e*_c>~fHh57k;9Kk&@`3^nzGZm!PqyOz_uhkD+rgN28oum{$z!`YamgZ&b zpQXV6u?0aJ7U>r#JAT6PZ6$sHJP)7K^ij&z|5xh_t5!!wcM(V9OQW{H;XfMMQNMNn z|Hifk4xq4)|M-;=kY_&F3!bI|ooQ?Q!hMJ-hI7EKs&d&Y+ROaqS~52Cx_#fdx?BBo z{ngv(Vx(JqQ}wlxuETw}n|MX|U_iw7t}=ct?VpX_C*%5m{rJy1$VzZDhI4HVux3w9 zy#ot(Zx;6L=2%Vs%k94&H#>yaU;8_R#W%3Hj(OXJFlkDBXuqueS!i#`rWj$hb?g== z8)MdbK8^l8BiD{$2asz&vA@Z^pFZ3uMR_LHyEr08-1;BM{_6-W*rXP}Veub}+yxe! zsQ+=!{|L3GCZIZgzeZAKiT(f7+tbKv0w;k=qEky@i^4tpuk`=z#|$_!QIMd-_6|{S zsXmeJw_T3VUHXiS>(${3VzZy8Zy5I0bN?#Kh5sfW0n3%)ZE&!=y?=`A^`~7<2}r4u zUqgT@A6K_tKM0LR6VzslwNQ}Qj+Ex#cS}kzLvO)=Fo#9$kDwLSR-d+)&`rLvgan~B z@2wth?u3MdfdhHQe zb)QFxa`I|wVFbJ$c^1nRon)mAZyk^S8!~ow>U!H9&f;=%h#n7G#*$-*p;qe+;JaQA z@NCu_K|WvaRAwroqUud9;x4T~j@Mi5YCT?@5RZg@XK7~Olk$7su6xPG=khjQH_)@m znb#B@{~NFUhW@_a>VY_{mSDWNI1!Zj#qfCL2aJM=2wQ;K-Wr50s?sc!i3X`t42D9N z(as}zt45RQJ=*($Lv+OCoQkqSCgY#)J^u==)cir};-g1Of_YY>g*P&!`=~Uc|n-)^Y36m*eA`O0Q#uCVg7|5SFd} z2rTF35Z99hV3BCbYyLh3n{=Gvge3I31xDb$WYClbmu%tP3X|I6;7!ZSt+e-d@RCmE z$+Lo(r&X(um>8d&R2)9Kx{5dxcE(_{O9VqhrQy#4ktmxJ)wqvqmFH2NXl!WLNw;4yZ9PAO zSi!XQa7NlGmnz;3tvrO!FXAiLVR9~vGeW@m3Lh*P1<9v;`eXP`|$ zrNLIif}lH_ri z&6~nObnFDQ5?=aMJMQ)=6IKg9N9*)fO7muY27aun{AFD6`h?(@e=Nz-WfTT9Y0`iDbJ6+*yPZt*Y@cEHoAaA96#WYlr}WCPCM)w?ap%(o+><8Ehc`Ot~7@Gcg*Hzv}a&c7>M zISDD3;`06D1ip_IZ3JI3brYoCnCPtWqtofN!)7sThnlki3@1wzYw7-v;tSZzOdql9-Cm9-W5 zJ01Yq$BSiH7oP+-BVK`k5^x0&idpO`8s7C_LTcaCQ-*ZP(U8W*MulQYbmg%ZZ5fYh zG9)Cbnc38Qb$S#HEQWiV?SL)*@3%YzRw2$CFQpNqWs6hu4RdgVZ;H#rl{1gc+IOI(XTgsf30q5w(x$ zz_xFUluG8m-p30@Z{^b8Aj%GJl1F#Mn#7ZbFW+C~yKHjW0Tnd88x$j^nb@t)ahAGK z(ib?`)$a|YCfvp^QigNI); z290Nk$k5^9fJHe{aVdg(hc$MFqf=AB`As8cf%oY9H`$FO5AWGus~cY6!Wna-JMh=b zZ%YQ7X>+%)yKnK-w5tb-f*W7X0!FzVh_0ZS8t|afRoYMERBTe(EhR=6{^Naxa$KFJDwtg)0ty+$9HpzR~Api&lji#TB zJG_#qq~0&JcM92d@+Pfq2HykTGhWGNq>5(}%dD{qISgp<*Qc*i`-i#Ex;f#!?^(=3 zU&B24xe7Ni|8`NPr1!Hr%RBGF%-f5yMkK)8#`eG0m>>MeO?cPF48*fIh_8?KJp6`eswReBNVlFtW}o;TFMqK6O`itl`}Wwh6q|Y7 z+be}V+Pte%%MUj7Cp{)IEKKQPvn7QRk^i%9B={T6!D$g#az)pr0Xl8#74IYmK|$E) zH%8gk3{$?r*4hW9u6?~i(gX@i^Uo=A(`g0eoj@cQSgZG2dj#!PLwnL|!PREm7l0l| z?%$l8n%HLm|F(!<0B9XNc5t)(NxVBge%Xuh_nv>P!;+8_tZoW!dl|N6C{wg1JDwW0 zl=C8q{`~#vGGwc>93dPQnjiP1ghZdSt`Wvq!MC+zM{7 zDithkez5X_dpMJNJpvuN93)0}fbdi{1%E6^cjD8EbTwlU4pstPH$-{o;sr9fY^=OkEb(0D&0zZqx z<204-cCqDo`!;K8@I@KBU$BF@f4jaoM`sP$Qj56*Ft%jJqVHyhj?C$Ra{WGa&T9VD zFmk&ncyXpY*cOA>KeMIpQ#1_Co2+kM^2r(0ILyiEvnCX8*GY0%E(;GEu(H}oiK5*7 zfE$(K{un;Yw%hdO8{(XVB-VcXIV`T6_ntE4a9v7t`^>@^`!J=78@rbf3ww^cR?*+L z;MsYQ=4miv;PXCGa$D;(Z1+B%9sSHT&s4C$RWZ`!H-f>B2DL^7h;*r4h66$)taZ>f ztzOnmFeWLT>1;O%)m|N~kHWVN>mU%hTHdXmu?;Fm=XI@=O`n~bYTwxjcsfXP{uplE zEucAZkq}g-)QA}@>2v(7c-~q6Xxe-I#GkFQz_XIL1-=1`=n(t0cwficTw0&)IFQtM z-ok5bHM0ICasL{8Fs023Fzk%!3lAh5KE=!p>*C)Ld#Us={C=iNb24WhGlF5G`xLJE zplmbQYIJKHj}N0-{VwpGq$~IVce{JAl;?M(y9V%r?G~c8oJ@2h6Q8$S@=LArr!>5r z(;Mf8Brcf$7~y#n-_C6fkNvg^Tg!XLb@TpwNd=ewdD8!KUUa8?pm4Y{-0baE^mTA( zFdkwO%dQiUUU(m~B(jcR0me~d<{U7p4}*SQlSLjG$&h6`bY)jtM+TF&5q_DlSt)D^ zen1>=AiLN7<>+Yu=0Osw?NV&RgU||Ik{H@W5!NngL|QhAAHMmW6)aZEjoGNv2Cpq^ z6$Qz!Mssd&wtR)N7aFb>M~Z*b&U~BBL_bi)sY&LIy^{eKb+NiJu3(P|Fq z&%9*50%ILx8M0yCJpW7VQ-YR;EHBn~2$ zxqAXx-Xd>DchfCE%~$?FY1hC!ro7N;3jM@v=gl9IZzMAHDhnhfg$=Ak>Vl#>V23*u!2 zsqtEudZyyMG!L)tTZ778v*sqWnodl)?^YD)A>N1GDRu9fNnuu`^+EL)$U-Il`I?D# z%^6~u_0A_Y`;)yD^SCYU3NWex68XI&hPr06u!BG3lSXz`OUBEK%Ms1z)Y@Hfs@*!( zwEgS8Six8MmA#r0O^lf*&qY|C=xA=3VXSpbMSN5Cx>ApkV)1eC>mfj*tt(qAJ@Y&8 zFa{@xK4p<%|1H($Bcw>%ub%y>51AD~sF4}spj+XJ!Ey?qCi@}Qm_?LtUCvwR5eN`wP!Uno@5D z0xf7oH)Gz_TbP}_d+Evbiqu(nuveA;%#9H#i-wMhZTwLRnLWLs{!R-^i3Hc535h0s zMu6rZ&dQjvn#Lp377h9nKK`V6kx(t99}-$Eqpkg>GSvY3u`RD!BGP>AqCif zV$nxEL~z#7;$Uk(wqWutb*~<|`*taeu58uJxk&FRWa z>-CDTt>}aac+QcrLZkwVNo><|jQUe4M+=J0X#Idyz3=5(FG?(GT2u*9890}3cpd^P zSoDy`eyog|Y?gi`~5;8>*1r@FquXM#KFNm7$cz+2E zm<(DD{yZPPCkG0yXjBZgHVpm5Wm_X3M~)0jI}w>SLR46O9gF4M37b!612mWaM^}sU zSw&0z@Rt`)RkPbW@bTXbJTLxp-?rP8)8JZ09Kcw%n6WzvM;o<6>E6hz+JAcmO~&WWEb5@D&6h7+k8g}~+YUWRmB z_% z5QpdcxTOhOkzuE>hdbUdtzANF>D^kIsOpu)Z}L=xovwYtXwSDFL~r z)6>$^c}{b$H&+!#EKMSZYgIKd6;GKsm#;$j3{_+$v3y3H5Ym}w>cluX1nVUB6hOwgZ5VUYgwr`6pV zaZcC)qrE7d@IZN2>q|3_wBw{)$xAaGCkQ z;`Ih@5N%3co}k!HvHa+2MW-SBzC?WF<^r$W!HGd&7bp08Ha4a<4OrAYQizC*6@>G2 zkj=a5!u6Xm)DgIeMl_haRh(xrWUJu|2hy*J75d#Nj<;xEwsr#DJiTna;LRSe%O>RA zLaeLa5^q7l9)Kin8rnilr3cx!cF|x0?J-4|!f%=*v8f<$Uhx$AETl>dUubz5U4%k=gw2uuzT3lQK*;r5Sr|LFVu&7Wyxr1#$1)ZVn)2*L#FEYF zh04|EcbU)pusBBtV?qqKj`{e%2x`HlwEM~7#HN?~0td8AItGJp-ZgfOrtAk%G#dxB z{@!>3(CbOW9#b@xV+JRcl#VlD?0EvuO}>xWRXGZxF;rio%(P1i;hEE6m|w726Eo)O z4L8V)x%y?kX?~ZL{pM)*CG`4vM;voG!rM8Q+*%RdnCihaxJRT`AbMzj+x#AqB9-kM zO!%?BK@{aZp?{$RwTWh>d(b-V87QCoF6CYk22tC^ zge}E}{%XDW{RdBVaBbHKNjh7~d-(4V zn>VWiGrQq6B9qe<`sO%c?HfD)l!!}D7oN~Pd`}N}+S`Jg*WCw<)ntk#+3H>5tXU>$ zTn1Lo&sj`2*_V6Q?F{``yk)P=zS5T6=}TYp>0ugJJpF2pyC}p`vAdWS`J?M| z8{Xlr4=y5nRb)KGSc5Nt?@F^j=wznvPc^vZUX+z29q=Xj(q( z*=$WM`#a5YdLON>7opBwRv-E=Obm3@E_;&tu*7CS7n zV=!KoKLZh91+?bnNa)Sr$2%}3cznJRh>5oE<2fJPD47I>dDxnjEgaCYv6>zq0V;oJ zDh*U=RR6O%xu8>?4h_Rx~-3McDy-t;Piky_ypcIpelWd7N*nlBXWxL^Pzel${(# z%$JifPn{@9b8ouK3`WYid>oVr$s6<2`OQ+U)~8SDwCJGih%xC*s3O~mL@N8uA9cA* zKpO0G6zIBllzA=MduTIw>5MoDl0tb~;fe+k#e;|{L6m=UxSQu#sno0=gq47w{5?w} z9AAoPbLos{@zaFEi*sRAwvY*Mc2uE9A6Xg2h(>JJb2a07lF_>Ra& z=eRIiAli$0E4xZKZ@T8CZiOCw=0=rUoAWw3rt0|JYsiQKYCD6Su@b+K%eFN{bshCQxgYWHRy7PMhc1< z)!fUxvKJRNsd8lB&}$CKuck0*Q<9xBG`3{N?)U$)DeceXy+B{QB|QeorKcQ^705}QQ^<52?FLnE?rQg9xi=qB;1M;25iK-Ydo0QW$ zj(icj+d^JArM=~wgf3v$9zEvUD1%4+Hs=25L&7NSJ zt=4gWKMXs-@%tkxgNN>YR(tVBXA)@nex@*r)p$S0cz?eG=$C4=HzDm-W?XWqVw84! zyze$FYtL0>+*mKahP$=XgzBbJM^{yvRxyDs^ygOp_YaOaoxGQxPjIQajAqZp}vrfKYiXOThN9lM#9Fml~X;KLj27}jY>@_3%;_%7z z0oLDLN56FuyjEtv(Nl}Iqb}H22M!ysnnx3}YUC;;RHy0{d2?OY~fn7@BH z%8fzZppv#68wn_M!%cM~M_+l-c`R3|%9}#Rr^5GayY3)5oB<*K$^|#O`rO>@z}@tp z!rx9lZ(01mg(chiF`071{T-~!sL2x~DAmZbcen;Z8skdXizR(E7GGv9S=Rjcmk}%|* z3J3u4R`}Rtdhy+HKLvL#nM_pH$(W`zLulj)nPZ7ze*jkSL42@t7p2EjOE^7SfE4^+ z79bD2M?O&Lk*9)7_GYuNV2LhUg9sg;4lf8HG>z4Ql^;KK;sjz9Bs2h=LsD3)TpH@} zPq-i$8^~z_`H2v8aLtpEPHh&Npv%jOno;mMyNkuAkua}LGA3XZCp>QwF71VehQDvcDWEo z6O1xmzV~s{8|w^MId^ZH+T!?^`wjq~k|EBRNP;xwbtAwEu;rPl1uN+otpRtj@o%_D zTcK6?RXVc{p<(j*TWQuxo7}U_<6H_8U8b4UArRn%{T?abjp{W(U80D+@NB_?--p9$ zvA5+oEAsXJG>P|CRfW=&tCJXw%YMzI$D|0ee?SOw;-a2yPN_{@87Fn4p=Yb!r{Y4b z>lr~@4P!3Nz%ClzRWeCOp$B_pzXNByW)-OalG4fp*4(55>*`ykPSh47u}Oshse3ol zH+uP>d7I!uE9+AIltmVxyS~!!lT*M&YcCy}FHL3=nwOUy*2 zDy!ssOfKiv)2HQnoVIgZV*us;wr}R6l|hk33a9grGBCSEBYgqD<+Yaqce;)>)bet;GtHs9fNy`6V5LhPd zApM6O?=ME3^H48lT@ovi&Km_iKs*ReO!OXJ>3*DNh1URAaGb}Th*cDTDr0g%TbTe6 zPQNmHiHxR>3y+o2Aqul1IFa;H$3$8}jTFk0dp6ek0{(JT*yC{nRhPI;Iy)sMnr?c- zifB?#2wwSIRPJuc@g9Aa(sYZ5**1l(%7!BZsy#r>28 zkg`IR;s2z}rh=+#cM-OttDB)hCP?SfCEeY4epJ}Cu#-C;$|`GVX0{AlT?y>GHdZq7 zTMH=BdF{?C`!mgn0kYX&QGihIo`+#ykIhfBMQHG!ZCg%ZQl4YqviaaNorn!#i*e?L zB}}i$V5U$Jr&caa{U~%3t{w*qAb-Z3)MP@P$fNt48r%J zcmRGSDmaR*k5cZyEx+SyNf~F#butDrL@^vJyAktNg(Qq@G6+e7(uD?&7CnbnlqZfm z)q>}?_$6uhkCOVF9tstTIFkapWTw$LtOo6WsSnTs1kHgR7c)n~MypOSpaxgnOBEDq z9&o2i(ld-NQW`j)vi}TID%l+|o=V7U7kjPPuak|Ol)L>x zmZedQ(m7&2Nao)Yo|bWekHjo)6tm&B+;-?~+xkSgYb$u=@CFYbT|yB}R~r<5^2N(;cg+{waE=)lX+PNGYiAv75!4d49FQN3&TIL%zk1xc*#Q8R#|ItcJ!J>Rwl{?^Fp%e!Z0X+ zdV&sq$Zl{e??=ofEnjWUt0kyS&WBZaN>QMBzm#A(#a?M%G@O9!yb_6I7Flv}5kqaq zI%R5tMQn1aj6Qw!>ZbfjjcCO*Iz%pzyA0Lb7pOXsW1v0_H~9Ld8Ty#MMfWZDS` zURSV-l*^e~--_`yD79x9I1RpefLU;??+7ZZmSp9f50#ckCA^YA;2*BHRnZVa>lIN6 zlC}nhEVy2lmovS8>S=!SN?G)UR=T3a6vdcn&!d&@tU;}iYNn>uI8Ol)VxGMMH~=~8 za6DW(`2je_k~obfb6l2)phw)Fl9U}(brk^+R_F}vBwxtI^<3z$b#b7Oj4v zMc``dt{9i_$l`!_Tbp-Wl6ZMhP-NjkBjC3;98NX^ zr-Y6rJCCc9z}J4+844-ufa)*)*1Vw4f#RV{R7U~fdOwbDHxI1? zx58)E$=5VQXsRGuq%rw?7f{?gNUP`hy)@m8 z_&iGOvf>REJhZsd(0ifX3pl#ooJ*GP0pH?M>G6JEUFrjzWDdeb zZRw)BJ~{lCChP092KK;WOWKrm@R&rI=+W8$>e%Ld1hl|L`npga3Pr7MtV5=Ss=aL= z{12y;rv;lP%Jfpz3{f9(@tO17;KmnT`&2pDT zN|NEX`kl*`9Lq~RhP(#$7!i3Kc=&ni*q6#ra%4COSA;&cX!wKpCQJvc?iQBvsmPRU z%EZz)dFua_^&Cd%#+F+{%KbnTE93kO)AQXXAFJ%YN}-9knxkr@8}d2l^_%2EAkQB7 zL7+{tCgwjp*rz83(iU+X7DGX;>71lsBoJj;kpRW(2-?WUS@KxdZNOQv0EPW~{aGJM zoY*&1%2eo1agRm({ZZEaqgJ=ZU|E5?*`c`ME;+R>2C>TTvWHPIK8p2*6Q0jq}X-^8I2{3 zeSLLPoOcz3-y!N6e-vE@_emXY?)x?X){Jf6O%~|s>f$jnF;NNQ{p(j|Qk}t3e-&P) z)6F$6B3S-sN>aFv%#8D$%R>>-2BL`u>0T&#Marndt$Sd^R^#Hc0$~#cNwOjsy5u{LPI)in-PG9IBdIUZDjd}m@P;We$!dsID zo94My^dYMk2mx>ReqPEQiSnFHU^DX%19gJ6OM9H8?-l;H=b~0Z3jl1jJ2DzyC^_Bi z;A3NB2MA((3J3M4GZ}Nfmi39~HTsKzNeAmb;lcYc#R&E*h1!wB0)QoXB%pmIkNsK) z_4}6hS$ULVa(*2{W4@pmg7B(=7DX}dR6_oPRKud9m#6<;%Xw}Db6ubR_uDz+OB&@2 zURqMZWO&(UwQJ<#pb?1M`$FT|_+xe#7~Wfjw{E`O(Ht-th0P3R_F+bXYa=wfd#|8q z9vqa^!AVmQ7?3}%eaewMa3>ZV)Acz7?Mgui+Hlk?FhL)yR=Z$EexGK;mr1gru3Zjf ze5VCoA=)7zadu@uapF`4j>$mnFbwNZ$H`4Ne5mpT~%9p=C-LH?@cZc2r~7TKgB4b1Xxz@_o&cr8b;!=T33sBtFQRsowAuup#bOES39&Z(hv&tT zbIB&*zrTq@a40gcjJ|3mEg<+%;B#w-d1yh2KoG4k#0JpRxNE}w>E7d+ThTa@ zi>N3JPigGnZ(FLCFNy*1DF^yth^{$LmKx75(`*5q?laS^?Q;EgJV=cKc1zNgs`cO9 zo!hYLn(UJF_S6j%s6#nNBhhPZ^^eg;j&5)9G=0R< z0kP{*l%ltfqu`*w51~bMY~y1d?HG|}p&Pn&B#m%GK zDJ6QGqR&_{i2PoHi#Z>LxDA*xqEFX{@qom?cY*GQkY_R@xM7-;_WbW@s@|Wv!lg!e zE>|qVsf&%18SH%GA*IKM7MP@F)H^*joDmvs-J}!|GzqQ=a|bKQh%E_h%&}>^mp2wPlbOPE_LUfiu4^s*vo-s=)cQQq zycmI1iy#7vz~!$wgC>U=6u>aoq3E(mk}NcSGsyCC1|S1VzCa|QrGYKM>ER$1wwle7 z4g(CgWvhL#{xad@JH8M*v`BJQ#jmm4fIe0zfU+7@ZojyEc9@6Wqt~Q`OxAj1EK=@9 z3|c%6P%2&z!xLieSK`jbvF(Y{pzd^$+ZL$YV8+pRAknBJ(83BXf|TJ~&?y(tbS*Wa zf4lF|^4Q@ZEj^(V;S&kG_h}~1p{Db72`e#KEK9N`92nH8$0VRWe;Q=}t++M_f=xTd zrfZY-+9X~$v5NtwtcNMTYVR=`g#}4V&=i=wcZNo?db(p&1OWI44?Ry zq3`iVPu=N7+5N7E!ept4XuGJsT`60vmuf5p{{aHs9hiXs(L0_@G&HKp;scUJAMLvHp1YZMtYevd9BBPyMwU4g zdOP-_2^K&PH-GFM#sm+N}ESXt)H{dcmdwwGla@KjJ&Cl8z~ z)BxjyH-V;PR7&R+$MQxB1rb2r&B+XB5h4m*@r_UbJ`H8pLeEW!`UdbF9{eH@xh&3} zC;H%K;Rjeerrk5MS$)Iaxb6lu#?9`sET$?`wE;?1ONhrds>JE!yy5Vhi)FajW|| z2~ZpHJ;T~udv^7a8-Z8q4m89Pj^+t2)XQ-qBW1wGuJIEp=a2C99mxmaN^0f_j#}26 z%u8==Skb*_FMt*9zG@3x5qfy#E2@gEo?48(96486xh~|T9uP)`nqA>=(BXN#f;1<<|Iv>>?PN~?D?YR#2voG$!H~Dn%14Z?n4^R zHK{e8WADnrGuW$b9LNtDd+h4HudAC z&{L3aWnk!pFe7uM*w9-e$alrgX?v&Uxt)~ZAo(p7V)PLIn`Qi&588;nl@dF&g?C1D z^kfvs5j6czY@s|LY{YD*jS+{vCX{~{D`xQs0zl24=DJMT_FlPoJ9tJAmYTm`{q{$* zvg0NNKKUr86Qe8)+`-YYKYCUr28UHrFurf>DrVDG%tE7ruXg_V; zGikMni#Zx5Y{au^ug&oaCHQEjQM172p>ePML*$dK26yH2IeaK)L9vXs0DC$Qq8MC-3?>0Nm1RQJ`7#X=qMR=x)W3 zl)?4Y*v)$Wo0SeNEc$)`<`BDX?|E%|lM}Wvwt5GRH0K*emuCa_5VAMgR}vz zR`aV=PEL#C-qGu45r`~|)^%*9O)_FOMcgu4tV8s$_@(r)xs-5dIdN8~VGe1mpfe}Z zarP!sCzUtmrso40-te;7EYz*Pc|r$LXK)S)KQo}6RC64D9i_F4MX^7PCD@CoQ=}ud ziy_tQ3$bOh9b6X%@oW=8EMiOkbmt!DamUbU$7Sx6VEs3I&KVkZLUJkv9G31$(btSe zf_|e3pZ>r|y5YRz08|&prJKz3q*3ZKbynJeAT>6HTx9G>-W_vbXz;+8ec`{8Fs8u0 zrl*28JKgiun(XBKH(d{QE~#`E#3A>KgK!A_R}y>P_|mHF%rp8sKW~4ncDk?;;m-Zx z&J{czIqXptD;%v$QAsmk^IEaer9$!8l`-qwuwzoFY&BEIIf z{|qChW(Qd6Xr7qLgi$fe@yAb5vGjrj-|Ic6`1%Nb5Yqkms@!1{ID)Hu^g4l5%x5|^ z*c+<6o1mY`GRQ;X+%e?+KQz5#cxGMCFg&$w+qOBiF}2&Xwr$(CZM&V?wr!j9^}3($ z{kxCs>?AuY$;wKy#y;KK&XaiTUZS)V7)WDBOsx8D=849#K8VS+`A{1NDv|#l<#eD! z+5+)tTfDe#Ib*E1SVwBvw2Ou+l4QAymuT4?;U4!QorVsHL3DaMZ@9#-GQB#?v8x!| znW8YkblX{ZpZQNPNA81pLHWZeO4Oo--?Som$gVE6l-vcs?76zn4W#OQ$L#q2Lz-#w zi{d@nn?Giodx?K}B16>srZ?}E88p9tk=}M=J<(VDR;`MUr-IYM(C=|8Ia2{1wv-*` z{~}Xg-vyD;wc-d;@9Ts=n6`@Sz&ewVpXtLQSvH(^Rf7hI6+B!u+S|@wnH89yl?mu4 z1V}hpne(Xfe8XxJ70h5dqQy8|7iZwv{#}GP->V{T7IoofK8O9w%^5Uu=R^g1^(qKSxvXE8Z6&T8V5Q|h5*u9%9a>L-xbq>(xO2TQIyw@G2{%LzFsHd7*- zdB~-{FuL*eop<f)JfiH$~&@xcT zPVpUsvi-)%jbpOkk>M+d{i}BHuDM_r4U1UhnuEb4h6koJiWf&q$|faUo}mObB1Og4 zmdMddkJOP&TZ*PBC0Jx2W5j5BW5$SG^8h;iG}cg_nE{_Ww8I%5d~B-zFuncNA+DXP zZP@K1_8`ulxGrA-Fflb%qCb#DmG+4;dozxYs1jsGu33^D(6cYOjSreOVV8X(aoE$0 zc<{kKtg7)hXL%p(Y|JP8V5+H_Exgl}u1*=oZs=l!z&9#Uo?ipUkvXU(cKM;s^WN?b z0RytQR4uX9MrF&KpP99AMmvNAc8UR4RzGVg&^~7$Z2gz=>m&Sd+=!ptKI;pitB_N1Ict86r5${8eo$6!jh@(Vk%TSIyDpk01G z7tBDZ$JwW*CYmgCGBnJF1EA%CTS}a8Ie8Y7Z%FFVrMdyXt5~Qg#8r{1Z%3*D1E$mG zo0QAuHiw{PoWh6jz>gx4S5-}!UYTQIi}W1_$3AMsFWFK?Fwk!W^t=tAp%Eb~ zg&s{#wm2~UZtz$W9PM8?zvmpA4tOS=m@_v0M3YJ#QL9*4H}|I|9Vc_3Q)11c5DHefY$N2UO>TXQaHrDx^ZZK;J`A@=JwRcj2I$eq|6ZGzcyi?Y6svby|b^9zS7KNR&q|m5V)T zGJu*S-WJiC6tE z9HtuSHV06kz>vq%6uieIBq0LC^L~ZL2e%a`<-oE*2&W>Pj&*0`+rR38unYCV4=uNu zEXNB7YD~TpYQel>f5rDWstWQD(h#>gL7rB>n@86iPYHp35-;s2s-8m4dRdKhy^X5J zeu|3fqKuA{;G_nK|lNeEM(_T)7_@AJLpzzsPhTj_!s1tfS$E zMHl%(nRFqgU}+tw+h^iYd>rt=}+B2=YW&^_!f=oZ@}`GczkVB$PuJ{%|Ebb)~GE1S85U ztDbQ_1_L~evvUm|Luq|(w+;E03-_NTKTCrNoK>pb`ZLa3CIZKwf~v8|t6wHfPJqSX zm>8ZljXtMPfU6-T$J&2M@UIczAR!Ptk3;3C=u!k$(iGNtcxe#2yH6D0Z%HXc1o5!3*fiCq{6CDJ=#^8O@gh2>P4Z0|$f64-2#VlxVY`?;8eS`x8WvYlT{sAcYT zb4-75{$DKsZii%$Jfkuhqpoqf^0)$d^vg)OdbrUnvqLR~7(0S2EKA<}rlOi|FR}>t zT*z3e)gnqgv6#h^gAp)KI~grW#5vOx=3?|vIXMTk*6bvZ|<(2?y@{Z9QO z7SPB-F`Z5oi(>3L8H-4!pV}fNjb(7B3Va2TCzk(_DS4`Ltc_hfJfrv`sr9k-!M;`km~Hb z$T0@>q6ii&OycoDVJJ<5B>f;aZIwB^z(U%nVR|-dY#ud^f2eT^=uxWPfw?A^1AX5R zk~RphYTcG{LA<4*40#jQ(Zyyl{0ek0nBY@fdM2D0gtW9D+rR**jK?XmnMn9aUDa6< z)pf9DvNS}
    #Tj~QIOyzKl5(NhG7&?QM8-7Q{9N}9`0AcNu;~6+3Qe;hLgwMjZQHK+PfjsS&Cf; z^?&__KU`cH<$-HFFZv^87Ix|G?iqh{h%Z>2G0|R_tB^(#Iyk45#E8^z;FLG*%N#wY z$w-cKrU@JxJK|Hfh>A>|dtAjFg`1M-R~kopT9PZU5EBUEwd_Le&rE7`KZ|no7l*iD zU4oAKkEZ@o#O?_a;`1!evRQpA3-8s66c?^Hna)YAY^ZQ;C*b6+?omWPUCpGO?6tQ1 z5QlP-RPA*IY!W(ioXqLJpSPpw7tOGtcfp6bI{Q=VUSl0roXpB9bsc$vwPA^Z>k+#A zi$*yLGtFf?=*E)+W+aGgC2I3Uf`>OuCnZX(ja=CdzDR?ssVa(<#y4MeNz2 z^BJPjz#SRQpJlYa2P{Q3eYuW`ko$jh6LW&h`9JmuH2th|7Z5Aat#Cm!`JaA8-xOAQ zuX3J4WM$_I4^#`o5*&~PG%i3sfqtvT_0WZmp+I5i8Uw7L@2%EF3P+E z6ekeEsiV<*C;A`Tiae3ynf%Cv;60}Y6 z@T+NJ>w{SM$Z7f_TD8*{G&4Bhtbf@v0#M;F_gE)YIiyiKT<7V^XebUSBYwva^~rQ+ z&qGrtNU*1@g*UY@n#;g1hL_%t^Di7B;!~vtB*bQ~St{7Wr!_d{EB#SZrazt-F`z|E z_p-(oRS$MUEyqJ?=cFD<=|3NLblgg_89zxhU1Z|MDweng?WL2^*8k>*!__57Bn8FQ zQbb$*(A8D|(o6;Twg@W1@@Hd5n&>nr&^+P*J{q?@rCPu0KR*iPV!9n$M8;lJBIDza zGZ#04Y4-YE;z{HQ3M{Y%95DD%(M0@rD4z$>Na%>Peee%QTlG>lQA=I!lZPp@S~*L8Rf zXT)0{ZC?3CY*#KtYx6upp+?cy9(FME30#iE3)^)*23f6K?>`TgD&yuJjEgHDoyTH_ z!Q{n_3RiM%i;XXB)`A5*4X7=&abiCaHF|q8BK&Veudr}JN0%M0DUJ{t-gFnJkQZ`f zMLkYfoj4g}pH=SWTkrk4XXugKjx>iqT1`*5f4lC7dp!fF&voMh$T9wi_EH#0>Cn)e z#B#{stICy{g4~aWk7S<|7wmzJah?ZIm)YwIuX<#5lcHhqDFu;(MSG|W8Osm9KRgWY z2J@5|QPX=CXLZCUhS>laGrj-0+cMfn`O`0{Q(1-&M;a?PlR^^7J}%kUOng(p0X%MG ztwv1;jM9`v`x|ZXTpNsK*$$KWm7k_^J9Pf)!x3U}aA4k)2T$B`=K{@Y=1b+r!eK8w zJ+%)*xKbG0q{`Wlf;;xhx^xtI2=xr3VF08LpVAsFI2}ynMM8T(X0IR7ID73AicAXt z(*ApFRcQZ`lP#}`N(ssxIr^=FX_OQ%uy;FOTK6f>@I!MTlyA1zY8U(;X2!%}aZq#1 z%w#f8g>Eno*^FYmy(FLWDDg3zrA1ywIQBlp*c*^NOF#WxYC&DOijdr#)u~Ievx3J? zt|&w4Wt3#%brW@#sj_4v_U+VKNk1JG;ZtO14q7k#12}oPNwGjU0EVCKi}j#y7ykY$ z#(VDvQVP3IVWyhV-g2qi9q}t94Ak^+GF~qY>5V;cvF+L?rE)nJ2~hcT;z5 zdkMU(vT;stl%8KPZ*DT%1Kgrr6U-N4UiA3BU5KJtf)Uii8MX?uKDALClw+6&l6(6QJk~PZ)|0=B3NK~DXGSa-VJS@;P@pS{}-hA-2Y(G62&hgSiL!OLzHUnEJM0fZ885hPl z!K-=W11~bc{AnKTYKPGeO%->I9j2p%OEZ$k|%} zU}}t);0dOG7?s7Fo!9I2-ac*TUeD}A^VnJUTh{(=;I$jrZv177j3XtLpzwHwOsmOG zkVxPrQNS=rC9bk`D99~6<89S^aQ7}-dhK*w6!Q4U&@&N8bkMqgfh5}Itxd~J@?dwM za|xHa`$W;YpHj2de_|RbPJGj^{UlFHpQ|2Js<$0+V@vlpP@eSQVF|zLgAM;>a?5|G z#AfiEqd{>dy)RsLV&DP#j8mMCPzWJM6DGU1Ocg zx)^PjGXFDe^yyllOJ04^j+Z6*b~l%N7dqiV8}H}cwwRS02|}>I(B8pO5>BKigJhpk z`P=K&)s#AuJr4I$!!w;wRu`h@`WLW6Bn;zqgjcrOM%Q>CZOb<{uX@WC$%7&}?sCbm z0eRMK;kE{LUJ?inRUplr+Kk-?e+g+di^8^$j|l%2JzQknYvKj4mm5RiOth z5~ky~snuH-dUmL`ZklJ~I9s=a63?F;pd$G(ziL>yGDR}^0*gg zOn)Pcy@zG{_JJXQ-vMI!0^X~8P-7}hJz#F7v~U>A+|5+3>G-!!1Ax9>vci$NlehhI z2#2_sN10nhGE$$s5e$sSN^f%#?PrH)nfVWGrr zgR24uR}(w<8^Kn5AZ|=d~4l4ALgQ9qqY0Z0|lStncIRuI~{N&IrY$pt8q8JBtsJ z3GF`y8Y^S{7Yw#SJa^F8tb}1SbK(``tbRd zdzzz+dr<)G7boUrM@$V!BV#5}oi)=Us9ySYO0k0!p4*oyYBvKZ*vG_K<|g$vZg_d< zEto(D1?f}d1!!ZUaG*&*{Nv>+tM+#%h9kKt(G;b^wXH{>Rg)zEd#BDg8WlmhuT;~S zUY*L*0EXqxCJJKsk&pxJ!6#Ul(%z+L0wr^2b20K1*c;vEgO=Z$rTl})(chh}HqV$OE z@cB#2ex*>~?nZ@S1<3Rwxo!v>4RXv`qYA(Z9dXD1hMaWo*&N*s?j`WWsvq|3k=A!I z@m3ncsbf!F;D0j3gjQ1B@CsTIc;rptSwdRUBfu~k7oq(dGTc;Oj1 zm2j{5Q4=e`Ep1Id`{$DbdrcKaaL>TP?d*y%UpQ*?8S@_(10I;Dn5rrfnQh&$XE-=W z#umjDx_QWx!s`n4tj%8R9!;9Ja3!IuYF5L*j?(?HU{TJqBriM7ABU{^LW#Fs*wm*G z;HE*Q(Zz>6u?((ejpgP7$tRQ}O6aO#Y}}Jil*Mbye}!%~qCn5kk)0TcpY3>eG@!wG zBTrJ5fxyO(4}3PY8E%t~ygiJB zC$vN_+19fw&>lkUYdVoazorQ4soGn&tEw{nOW*HTf}b9CduVfsUoU7kwM9aVU{3_4 zGWSR3_NZznYnTS5*XN5lrt=jP&*aaA)l`cA1giGeu@>ik^@ZI=CJb&NS)rQ{c?$+= zJ|PE2d&3w}gae2EUBeT99p%hlmola}a#g{g0sD0LkkFh&b`5Zxo;0*VcPp)gJl)N? zrHFcOYupynq z0h;}|SxOj=7y}S!+AT^!6s;g|hpco{$VRoHG7Oh9-v+xshM*}Dn&JBP+Sy)DJ|l8c zgXqn&tSz(Bae@r(|75jpg$NMdwc|t5K@BOqTGgHC!iHElMhuXIrov~|Fhh^v{el=Q zq2?=rb}A;0hYn&GP$BuYm z`nS0-3lkxMj?xT{c)r1aIB$r=z5t4LgF+HoXMKn(ElU{~SLz9Au+wA2+pXQJrj;qc zoLmkAHAmw;G#Um-)-`b47+)4D(jLoK=gjgn@XXDQ_$uGg@$;cz0KiU%sjNPCBw-=; z(-;4Kj`}$IP9ao`Rll4R^BIE)ZIt|>!uccg`6 z(_y%!LTYS!+;O=7KzzS30ga4ntB9?zM(HXCG4Vz9CU+7e;e`yo^Ts4Mk|6DL_obIM zA(JpZbVEk*(#(n{a#f2b+7%rp&e0(0HBDjd~mn~2sufU?I$jnN7z z_;Qx(pYhw!3G-!HQKddF?^j_CgW!NX%B=cvrNwh~1cF-nr~0>-#@p(3M0MJxj$3V6 zM7xIQsh0-QcBTRtn`g29Zyc<1H13Uhb!IZ8(r)8j7B7uRd&3*ULs?lQoFYU2rXJ(* zNVII@>(@1k!I*tK0qV$LtJ^<2F% zn*q38?rKmuzQp)Xp*CpkNSL0UyfK|dnRh*a`U!XD+EFhH9pq4pEk`>87~pbRbuM!p zU49zuYL9SuZay1OyjA)GMb?bVdpPod$AW`oMe?3!qrgM7?( zIVeo^%htVO_Kj3>tqW!yYhO7*2>EUJq5|QZ76#m9#nXtpP=1+HcfU^ z1?R8I6u3NN|A1GK%)AG}_1z}Hj)oX-4^9VC4iY^&_uDVGEJh8vg(d>l}vk7%`WhZaWIlnsLD8K}vGM2AFto2`e2Jn%j0(TfL-*#Ra#%Q+E_^ato`eH1hZ3Ne#i? ze%tYSirpGXf|*qxRB&{lZoS@G_%Kwa*PVnM&}#wgbM~SIp&$xCE@NmjvCk6HE&SSo z1$;>kR@3ndz)>>)ZIJj^u=7%1j4q z9?`(Rwjlu~;}8W$?+;*biucdi5*pg*d+{SO(~`gENpS2GLEJAzPv3Mk;nqvWEl*zA z;MNXVPv^S(cpn{g?uWA>ld0kk{0P&VtkM0&sD0r^S#p>mn>H_4lHV=bcb!V8%BV`I z4RpiB(-TZMrlbMN@+g-~=2@7T68zB)^I492aXs*QwkN07XL#Wd_tWcRV3Qzk)ZnMn z_@6Z)<_M^}@9|7-`&Y7<9>1y4s~bR4I;rQ5Hnh;w+*Vwg!cY(#{;*cGQvPL9;Y+*o zWWx6_#OZ*Kt2g4fWPu@-Ftyk#>cwS5GD}<;7ZnrZ+O-fIq&CIYKZr+uoaE7Z!{&ux z#G6SX6mcWw1Mvk*n7p`jle1f5%|E2Mel7JA6)ZYAKUrd(zjbz#A1whU6ATL8o>p+IM zB-?C^aBN$GgGc}aa5kF=1>_QfS4w2L5kb9Iuw&u1I4_?kN%uJBvcF_(n_r&3Db8N09x`bv^CFv<3*B&z%} z|H47rUD2SVKm?T}z{VidCc~2v_z{HO3gdD&{ zeUgGvAPN!GKy!QW!NU-va_lLxz1s%<5qcE%UEF9!h_kof0-h&8n4))IceWm-q@=88 zbfA#kQV>W;R0WU)l)w=YaA^I#5d{MEG^&VyK#Rh{9?7R>J>l|Kf-*qo8C)^GZ>F|& z>Bq>55`#E8*0!i@x4lf(Ty0%kQqbz4sv;wljH&wft%^czg7{Eot{zj4N-q9Z5Hli6gBEugNcHQW#ssV&1^4BkF^3>H0||00a&s33 zBx5slZ&@@(iDf34=f4RNI6mq z{97EqCAQ-gseDv(zIZ#uBFm;hNQ_jNJ#x&x{FQq6BMQ=&nkLyFQQ)E|goH(d$`9_P zmyr5fL*tOJ-HBqMB}+Cxv3lt_x84Yq0Bp-67)Ph~9XFK9fl*rb;q<}PM9JEAS;r4F17C>)<371XfCDmG(LD(9ab9xuaI z31HT)z%DLr7M_+6Vkxm|s1m|ry^>)`%Nl<>6|mf(b-s@UnwB!EjHzI%$`nl~rhe*D z64ijMQ{m5T#I>GSHHpkJ>_Q3Dh~km|g8?j@rw>VK8zu5krR-x;1~Ii^7?`JpH1!&n zDUoY$!~#IEf(_5vAXgbv01t_-^LRB)w4j@?Ka<)h(Riw(${aG#>|Uc^H_MW<>Cn8A zl1(lpE3HTz25iu2;gSsLqmSsKWC!~pQrZD$FzE*x8gW}iN7VR}(d)<^nXDx(I+m`L za&VT11MFT1=2r&C@w22ibOo-uu|vXq<4C~LB9R@3#O!*m`x3oTD2-HgU#~qmd?LtlbS&Z zA|k>ct*$4JOG*kVD=YJ2NxM{_4y4*PuJ56rr@YzU7uH*_Q`X7=O`M=ty`T%j`=_T;rJ0j0O3>aTSwej{lZ=M65ogJ4xsQ@1(Weqff9SYI1k%k- z=3Xe-W8QKMalq_dy!2T{Q;eDvB6_DUXrmQw>j2RGd;If1`> zZIOiTBmuV_{OK7KQS&)j9umo6Jgh$#1(cK_;0G2Jt-zEpcB%Vf9_d8sBS7$S94MsR z>vM;e&#uw8RQ4zT}PZtrI|hmY19h_Tf4O!#}8x09$`|IN@X`&Do@OPugzeLgnNDX9&N7iB%NbZJ?i^BE%V0gA+%4w_>Vvf) zI+SWDfDS?2jB|M>io#^`t|V0%=5W>fJ8F-0`}_g@d#eF6FbP&qM#E9FG67ID{yfyC zv606=W<}NLasYhq)V}Sa-gZN(>UCFEQTvIacMu?i67S@Upi7RB{&c}?f?hxy9S)NT z^Dnf7ctp-&5S;gR*{TYbV_($}6~E>h=tUF3XiLNai3v%()@Cs8o!_o}6TNZ3=oGsn zV$4Ut=}tZa*nhTbZ!_ zkTs?hTtVSUDBLddKPT5mH$&sDJeFcpF}il}gBus*O56Ih{2pj}uobz*T~9YEBV{N9 z_Uvt<0y`)h@>)-L8*UDz>TGxTCR zT=_2Pr}F@YpXGE%mWL(7p3$X|V|4#8sm*>?!6KfF`6ci3{q4U4Ec1G-Ws0n*x#9 z5p^5C2{9wwPV8e(+0Gx3rTN0<<73PmQ;#T}K7zj;9y=hX|GkmS)SyN4sdG%01-aq3 zO~XG}F>5xC>F)}16Zp@Q=jl2eb8*b13oTa0eG=*g059Z3yrXYpcU6twG?X zk7;7n1xY~g4865Spb&Ve^o#lf(x z>2ynu;7`SIt!jte1IYK=JJ_F_&YY+_Y^U2+nHD(?8B5P|+*wGzPH+nv_^Y2@OAuBKisq-@~+H6oS?lZ|hg%&{ zZmqsn)b>9~xuK;0pfh7ymOd34T?n(=9axLO@-+Auta1ckU|O>FG2>orsZhd_0eLtO zuld$9A5;#&31|&4p5%zV4`BS&hSYI*A*9dx~;9Ckn1shrgjZ;7up=<2VvT`_45S8W)WynkSq|q_g@DMfY6r zp<02NM0E$*xev4|J*&6FAU9&-n;G)-Iy+vyrraagsBQ{vbNMkJB?MrxTH!Zb;DRxV zZ{eDK(&ryn*qcPbY_HTJupOF7hk~a9eV>LQA1VTEvNwnn(p9^)HQY{LTue8NFJzWY zYsd@PC1zdw^m*rN3AW#E1gx;v6)@r|yQ$uB|JJ_tPv)IYVk$C7VA3%B z&mo3@y17){|LEa;=|oa!`BtyvLe`Hn*-|V|hCyfeLQtcd0h7Plf*i@?FB5~`p9)(D zyRV5Pvh|9PU*|EHx|2QxQXTls;HG~zyg;c^N`%dB6-NE7>N`lU>@5{#z26RUarP(* zd%Xo-96blwC_6b^@7XN&2Yc0v72R1PGz9LVFss$XcnV6*{&ErRD&347aHb)n#-8W% zq;yUUh2M;sxWX6EkfdI{Wponv{n=(l61w0ZmK3nTBw1i?5Z6ouYeGRkQ05}Ltpki zXYBQEQD@wiaZivNz5Cvn96v3?aH5&b)P5uM(+w>okU^W&&P(u^-Stby2S4DK=2YRc zc&Am40e9g^QDfRZ3v}|B6MjPFRE%%VHGPK|suci98JD^G7fW$3WK z>WMEQnxF`K2NC_xYFP(X1)8~98!$_~6$HeIv;rP64P~xPh1!Zi`S!XLN7n{|=q4P^omX9Lqq&$%Mo} zAb9FxZq`ONJj>6GHQrh)QfEfyPYPuooUez#yO67=qCyWB!;m^&+yJX!;6}nXR-V{k zh)>rAXiGAgR!CP0z_^!?ii}|IB}(dSl9TYgP3CM@8EcY1Kc%SuXCAqMbfsNRrnAdb zD$&a=?�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 diff --git a/doc/src/docbkx/openstack-object-storage-admin/figures/cyberduck_swift_uploads.png b/doc/src/docbkx/openstack-object-storage-admin/figures/cyberduck_swift_uploads.png deleted file mode 100644 index 24aaca214c0dd5e0e31a08b840522b9de29261a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63730 zcmYJ4Q+TC8)2>%mY^`Ww+cU9k+nm_8?M!TYf{AV0p4hgNJ>UQBfA52S59*-btFP*= zs;>L#2n9KDM7VEo0000{QbI%t004sh8^|zF|178Hh^PPn9F~Q!u!5wpFp+|z-A@Z^ zQvkpnY%#@51+DefgueOhl5I<-C#sSSaJ>>mbm-ubpu3&GD(^QZE z@q`(%k#YxQh2EH^#z^|{p|=QQLFpFWNjnTlC%}71#Y_F4mo)IHoR-O3zt3Ue?12Dc zfIwdDDv$wS!qql4v28!gWulyf=rMc4lT@hKv^P*UD^V@3$;jz3&VpP}h4IkLwb9L- ziT_|G%a-{@S>p@uN%?AU^sM5G=5;nU_~j@iCnf&YXf&={I&d8bK06|yOTYn+wH<>* z0RuI3%p?@X4X|L=Jaz-$ZV2gCMVXF~Hs;Es#3&rT-*!N_Pa6sq6B|GI!qxs1SJ!{M z2uk)tHbVK-+AHj=brhTKzN~4a(gbkLc8#KZX(?Ml2z*EIkF}O-BQkCz_{nJi1{)6K ziU*4nz%U2%Y4~;6164b7=?TSOI(V=TQJ41(N0gRf4!?Amjq) z^U!qw>OF||&yT#NWuksRd8t8B7o~gq{XNXYYo^UAKe&FV^%>>CWBt!87{v__N_V=#w-+Mu7wyT?ZBwf`B+oLCTz1hXet= z1U5>9xqxdn<5)VH!j>Ep^(hXU)oB4s3nZ`8a=VM)y@G^#;k1!4;GWzc1l3zZ9{ z3vndhQNdA>6U-AfNs>wMN%~1@L?Q}K3y=yjMVcd0B6CnXX}KuHK=UY0XvR?&Xq6yt zMmCBjA~|$+v?mOCOh%9$YBxC_X+Y{synRA=%1CnAuNE3+Nn!Jf@08!dno`x|+vPF~ z_Kq{0kv)N({=SKP0=cP4@!yjX5+)L>k~*lUO^6T>L!n6{6bCpau}!^Gl;R!ZBNNsb z7b$+wJqT*aWsu{OW;1Rw@REFJhEng5{GxJ_C{aF)pc7LQU(#n&er!2+S>@zx%ZkAh zXVAZF*dX=L&=cnq@NM_b_U?WU3@ixD1nTGO>{Rq+kq9Rgr{!rBxJx>yMU zoHb7%l@m{TWQN=aa3Hpp&pvzpDnSI;yOx=9DF>(5o7&N~?IO9xWy< zcrUn?HCFH{QC4VI43`tCUMYX&<(H#Y)X5hr8;dDx%?mqa{;WJSrmslpREt#mz2sw) z)l}?S@W^~2h_5j$Ln&9PbX3hyWmSz^<0a!Jfm~@;JUm~yh&x|;%zbQj+c=Koqa!>U-DZyUME{?Sed9=)WNN9^1Uef9ZA35G^A!e+z{39HY;adV?Ete)95#( zWGY(!O=BKu4G9*B5>Jow8y6hjG^elqAJ?^$g}rEwcFrSiULPx?oh3jqi?_LvLTJD$k9fzVfaQ7A0o`=8p=&vsy1AKUVkluLo zO1om4tLL$vJ)a34eRfMvQg@%C_@}m}yXU?<{1tm*{ksITwhwz!dY%Mh1w{q-dbN5_ zdOL{=h;fB7g!zKG!Z5?&`j>()5Zciha0v+iVg$s&M3{$bXk7jI9CnaN;_xjFIIn*t3N=i4gUOUT7|wJD>Bhlr}^q*E4$I45JF<}CSaJ#!QD zAoF}(Q{7-4tB&@i;iYw!kB-HLPKUC$==&MOQ}Agpazs}|OoX&#zU0Md@czjD9S^J? z$<-R>Aibt`=yTgUPZ!f5*MY=XN00POJY2D@%!O28p-~>cF6~GAeFQ>#^jLIUI&r$$ zpMiRJ%@1vtrpqm^&PkVb`E}-X&UG(0s;iZHW24gksSMqj>N4HVc2&2d%bYRSaoaWF zwO=hq%Xs}+yIF2t!cVS8H2Xh~`)R;`!bTSg2A4ASJ-U*LI0@W#|S! zU0Gw^!da$1hr9a5b>-33yk7FQ!3fp;T~DD)!9(%ZXqJ4gctct`wOLp1c;{(CcSkS% zd~<`__s99^ht=mYRJE6Gw@3fO&>~-0*EqY4onDKn&)K`p_-FF(mNMfDBi7OFC;4Yhg}PSF)MxK&p&y^M?`h-q!(3)xGm9PWR(jW& z?zOi2E8okGGYicu7bIwg0k;|kf_UpZIuOQkr>?DZ7bt7R;!EjDZ1_cfh70|CI0u{gkWIf z|E`~1eQc$tN)izB3c^fK5aNnXSE*v`|_%%rlubKS--fxxd~`)X7A|e$Rm#d zeuMlDXAXLPpjOb*ifpu6Hd?7Q43CZu9zS?}NSLv-#(<q28 zRTOz<@%=m2QQ^#CU~VsRKt34L0#BgaQ9{DgnKFr1^0Y7BmR}wIN2y+rMxnN(1qKiD z`{MXKR9p)q`K3=yXWKWoMmf&r20d!p*9?WNVkhDQ1-Mv3{#eCAvC+bMhEap99eaT! zIYyih_(F5I9?hqm@4^4GG(<%rN=j&o*qPnEy<|SkSJMN5#a3&6yW}{ zWypm5W+Qcvn1`k|8P(iN2KinQuC~F(%)H-YW}LAneqE5QkKaNHRj(`TE8)BU=uVT6 z?c;-B>A#IoK13l{HFO>#Y}ijvjx;XL6jgg>0`0Eav5cO-E-HQ1fwL!$eJA!L#Kd69 z$;t60RjJ8`UL{S1#Jnh zJjFajYWv***ny!Tns=J)`%!OqAmgA;FqRi@K#VxyU=I~x+PIU0y&G3wjO~s(E=IAo z+vRXfLO-*sFoEsGnFVXv=cI=Eh_$lDWQt_{`Ce0D2UOkmTcP5CG zYIY7Ct?ll(1aGs=MHvK`bc?owN_@3T)I9-F z^Zo+w9?_xKs7~MrJ+e!9N}Q5W5lB;a)8CGYi8*8p;#*Z3*htp6AF-!9SPUX9V7mRZ zQ#b@u-Y%)}#UbtMN11Zm!Qu_f{lh`7LmRixYWfupE#7vg>vMOZ5r^WgelY%e04}3+ zYPyMjv|DN&1?=}eHr{X_9@c1nUZv@<9sEO@EahcA+%+6ct=R{r>6_6K6HYl zDayg&NP*}6hFImWx@X?bE;PagR&TZHj3%y)%~TWQPEmd)=cX&A-Df*^ThXTSjmFF@ zxuCFzwuch=VQ{j>E<|?CNWT9K`N3(=b5_TC+>Pifbs3fK#s#nNKp;QLgOUK-msRbT z9B>rfwUJyX08#Wg_jd}QpqlLD>YFOC$gt0znwnap(GnvvG7{z6w+izrW@cs>WMuXK zx~N!2cohBcbg@!VM<*JkFFN8RFl`094_WbYv_7Rrr~YS*k{)09N}5Jrw5p!9p&{|U zrm`X10@Q`(Kc9G4sa2}($nPjt4kAP?P6>;nS7GS3yQ(J16+1100v;b6wIhF%W4$%m z9ZEQH$L?op!xc}C{W~4hhnhR8k~u&MpQq-II|?YVwCy}1<(#@)mzll;lh298IHS2B z*cD}+fOGohy}u6f#Dj-nw1gi(AI;l@koLOwVp`OZjvRZRLh;?8B%P#G!l7~eub9+s zdCrqo?kk6m4KJ2CyAQCJdvW(Wr$((uc~ zA=U64BrEgF9m7g?O5oRK7k0DHNvPf3WhD2OylLlw#+@Y_fww*RSjX#5-4!9pIoPwM z7gtUmt z_nrHfQ4!!5por}-mbbKs1f*tWmhR70EM(?{=bL#H&6vU$NhYhaR8kK@zQ!oi`D@{~*EU=TpyCYz%v-MCwH z@=)FtIlpp+Ut@J74gXwkd=-DNhIKtF!{cw|+175%k`7kz=H_OX6P;fiiVW<1u0g6KR?>IO# zt>e71!}mR=rcaapA5Ze4(RPbeRX>ZS_1 zmt-?1OEi>B(?y0GnT%!9pVsZx6NvUzjz!x!3i0=-gw``!v~dRgmtXfmeH zjHy_^@Iz}Q2JY0u!l|C$zKNvdByl|w0OyyA-R(Xdibh#8_lk~g`*Z3M?G%`5I!}a- z@z|W(-z_s1nyFu6FJ3c_QtijX%{k~85IP@fusN;1H{p4}852h?{^EFF#1GHw(_N~h z^i*r%TwAGQ^vv)bqP+46xF@~OyUGg!mqS`A(4YWjb3yknZwF6mcc~pjiAtZ5`2SL3 z>gx59w;m45%Figi0kvwEF68ihW0#o_Ikm5#|RQr|jQnhm7L|%6R&qf4+|r zdHb#dH`=c;AQlS>wE`;aN4S%OONcWwi=q+4=H};d;9npGJU5z zL=1Emmi*or9gQF&E>0`0CV~PVR1rSfr~$s;)!p5ls2*HPq@<6QR-oa0xseVhkd&x? zRUEeXQ(dnat43J3-+fCyfYxKt8?hHuQ0^}E!IhoLvb)z#GzFE>(YJGT6!-rAPO+n@ zueH0|*m|D|PkGoDCT+U&=h=Jgl_4F+w2|R9$=M(z|et z)p`v7yeIrFfjWoz`B*3%|4N@s!Pr~*r5lyNKHYa*M#u9u1noY2ZN|e>t*yIF6+bbu z^3M7w`ZSPd?i!A%wKZ^-!BMGi_PXYFJ>^De|3Y8SM57nC2hC2pXkAlX&t|~=8+WgC zD-7NXB7b}P+xuOmUoYk@gs-1ra)FWLaFpF==2oV2?a@5hF~RIYXyKL1YG2J&5QBCxXR) zScu0!9%#Fxf;$iN_Etu_bekHS^H498-hp4S<80hf5AA0g)JoY&+c5pB$d}B#$9t*>zfBWj|kLpt4rFi+snW zu)@uBe%L+FaYMkD)t#-(;%4|pZWz29+$=9YfK$<>_@XA7a*Hw^O$9JoO&|}n>=w9| zl_L39D{Vvs1_JNTmgRArqrkh#5}IAe%jFZP5?QEH`DCgd|3$c9gaTYC#7Y=C>M0eL zQ>-H>)xzrq+W}~SL>OHhLD)Sh9L+r~{lsGQ0uC4%i>xFE4t&sxZH##JK@O!1^*qW% zRTbUfe$6g5B354-eV^>DtqvSBkD*k0sKHWLw`;eLlE8_I==q7y&d4X&PjNGMZUm+x zygmq$z zhuLp#W8WI!<+Rd*J8kL4L`z?Z=;#*OaA9kXT+Q3ILX#F&@;SQlsm10LjRzjUEP1=( zbyj=f{epH0R++aOP>G#PD{X^z-pl`tA>fKJ*2##%XK==5MoMLP#u2qOzoZ+gcK;k? z-_~sci{tHE!B$;fwuX*5JZy#%QaZ(r5?=NCa*Len0lJNae= zF2kAd8R8864nMYWv*Jt^mnCm`*%7ia&!yj)&6p?rcpc+4MYe7y3NFLlnQgCfP7@wH z<}<0S0wE0;+yO6f)}z&prsA7+xy+9GZAey-r)&>zT9no2^|z%?Kjc@DSB2}SK%$Q- zLMZt*$h1EQ2Q|7;hOmEYld<~5v|7uy9}Qv?BU!q*7o7)j6X}L)tzoZ^LYfWDg&_Gj z6e0@*monVWryz}w?wC+nZ+drw+zlN;Y(7kxd|(ONFlcrAtlLO*>t2Y}7r5d37+1He zvhKXS(AD4rjH{bZOA5-trqoTJ#+(R#T7hSw6b9qs+^~gVER2N5Sc7LkP$nlAa-LtT zY8P}dc#Wz$3exXqaaG;F_5=nwTxS*Kn%g7YO1r*y9gOxaM^VhS+t}WX#)x9W6h?EM zJqtfh+)t3%3vffcL={^}W;%_A_F|+jd%@j)4;C|i1iSlYk~r=SP4}|~7sDB_$>e88 zfddnwZW#`;+1N+(w7p?NkqN6gXvg2M+zS8_x{VlMtw(CNI%BLj!N~YrAY67^6{z-3 z&j(ACkhVp*IFf?&NH)?wtt0>^1njib;#;El?Z2IxNGXH51Sb=_mYsE$*dMj*D4$c# zWZEh!ESV!+`a6RkLYz3~I*#mxKCCC1C$X71?J{v~%P9oNweycH6dP5sx`tN1!`Kty zA7+Cnpy$n9ZpBbA05}OhDmw3kv5Hk2Tsb%30Mw?VN5_3wsgG9xZpemTqzYehyrW*D z969144FUVk3q9z5kd1FF2L!#oyS}S0*`R#8QcQzp%`;U%5nR~qMm5#)*ns z_h=X@l=lwU;p(M1fRXpU5%<8&^5$O_>z6}F6W2DRU(>0Is55AIxYde2mi~S)+^zf0 zc=TvaoXPZXHi`f`5AEwQaD5_CsES1M&F90#bd3i3<&R9=hkT5yonNxfT=gY;Q64qM z(wL=88kY}8Shao}{?mV3uxfle@DDsPuTT4o_hU>tKA*weAI3NBktHhxKHw-L5Q)^} zr!Bxvwh!z%_Lv!M5OWaxFbh3ffB)HJe1Wf%+JA2X$7l4x8P~fR4(7w>#D)_OTY*l{ z8U0kjiaN{f1Wn7HM~s}@$vYxAJCb?5olD<5Hp0TdfAJy>>xOOmwL%bH{7`+my2a-} z@VQwSuD|Zx#B$0@4PXAn8F{FkYSuQTd;_05*;0fHt)htSi~AcsQ%{6l3sL9$QK4Ck zKU%Ti7-zO1_T9N~?Uyl$kj3ZMa{k>6`-|X&_ZLdXF2kU-`o+*<1JTAU;VZHNHt8tu zAHLRV2^~6@k9)MU0@k)#*ThVnXhsR8PiNkqB@T4kNpFsALiY{NA+Zk)SFAz-2cVY%EP$7#}|&R(Ebe2cdd0Q3{uc z!MK2C@QdUP0Zcx%q`QC`X88LrJ2@l=Ej8qXT$1+vc&k=MkNsv(dQ-^I9!t6(mar(m zv13jDv7Pd4IQ!%t#}qP;LHWEovKJLWeL@-4cxgQhUmttk8<4xD=Jb0`3mb;~^zE9< zTZuoN#ccsbkJ>$JRR*A=TCijJxGP`X!S_?S z5Y6{^U1p933)H`#u8oeYuYqUw;|)8<3aO@oqdOv(3H>95q|4K}bON{W+Ski>oESY* zW7#WpZTzbhTeAF`a@GT1zDRxa^12X&8KICe>J0$m20h|c#M)kWDMA zXlkOn0E00e>&LkCAg!uflxe2><6_%v--(!yRu=)+p*h{9#bn7diSN`l3IpHa%&R!< z)9+v)5j+q89zuI&nrnYQ)7Y-e~*qs3g_P;?2&pa zr)t$oNr0#ur2~p;;_7>vs6?>lwR6{z-prYX43&ZXp7QMh7KI{77)2Sfk_tRW@>@Ac z-eKz21G%7zDh*k8h0aJLS>w&W-93GvDa>@xTA@;Qtzs%*AfYMWV(IlQkous(Iaa~{ zO5a=dm>f7?*T|F%BKH5*%_v*i)%EUgp<0}fmJ(PIn>tw?$BvNy;jr}qTbq*8bNIyH ze>TqFdqv<28^rD8=&weHxoiuc5 z_}KTrC(S`Ks{jVuc~{9DrZSOnXd_iGppFDFD(4MakLG5m!wbrT;A)1o zljp5I*g7)VOvH9>(y6~T@+GBxW>rI}0_BH3&a?3ef&acTs>`twjND8(xCkzk z(DdYmnU8UFO<zV{mhg;oKUxgAscNzoA{`wa9qx}6WwJQx zL}LS#imSF#3x7x^=f?OfQ$E4CEKr5Rpr~qi<&d|lkUj0w$~dHNYG0*Yo{Tb2_YPi?CR^iP{-y?xeOc z`lu;0MmwdtLs;`5+VaLLJxch-j-z+(yJ8Hw-0xqt8H4$+)x9731rf6T<|=F2!u$7@ zmfRJ}s(~$%R}c__XB=|RWTpbB!(T}m&VO_~TsY$4@`3Ae&NZ)dn#oG{fV=4gGl6rL z)aGD&&A+U?cI%GRBUGc!>SY@IXHz&kn4{(gR!OE+3(b?0L)uUJnlwikwD$g*8k7H6DGyYi8w1gc!Fv zBdMnsV5sbp_KW@;mN~XIuMV*H=qqk7cwOpr|J6VFRo$`+H*#yveB&B%0t6Soo-?EV z;>a#8)=vk9@;%c9$@QxsOsb&CNs*{mm_&`x!9J5o&m7>7wSze4H^`J1jh1SbDa#`O zgK#q->=+s_K|#Sq7!Nob)Y`;g&I2tFpcQlfUjtC`P-juhvoGm3@n7O?L{UW=U7ty$ zr!MRRQHrV7DPVwkRKxkTQaah*21o{T(0{m65%GcDrv=*igAc)^?-p!DOmITY1*v}~ z{|=f;y?gR>kSjRp>JlLqYBJf~AOxa#5DcRs#FI3?lk72t*CPE)GPH+&y5-fj`1be* zK9}H9A6cY%u2Nv%4TK`ZJdzOGRnd(cCAoc7?5tL_%AEA<2ywhHO4Tb=Tu2Z<&^uKe zHO8Sx7*j<2)0)OPu7O9orQ7IldDpeK*4bK8pk3F>xT$M>{I*q4DYu}L!~F>dO!E}B zrz7O|b~SF{ocCZyZEvvS1{`+0?rv&GzYoF?p1mWt$jdm98n>GRth4xocl;9ZK>_vx z;MeCXEfFpDJV8XY*IFS`TZDzSq-?$@{rlQ!>Amt?m~6&($<<&nAk64S^~SG&_IBYQNGX_qg59NG_F5+!JE92PdieJj^;SM*- zkVM7VcItI~k2#BRqxb14xeNw==-#{@N!t?{e)D|6GU6>XESRT1#t^N6@GLpH(u~I9 zn;43T`vAjo-j-O=j0i-7Yl#=&kY=ehob>gDSnkOsMSh8XH+tJ6@s9hddWV(Q`GFnK zWc=)LAm)zPhL!D;HtdPF^?re|BF-Oj#(^d0KO!rAR8c(z1HVwnk#2ik_vAZVNv45GsjCOD%5rYTr zyxxEeiO5|rHB1Ggn5b58<9;#(XK1{7|j5?kC-juG+DeWYWg~ z^j2>h6;Mc>`6tqV4i`B4;RoWE$EBnq^N824>tkuGUWqHe1YRWQvmZrsLEV-k7UR9} z)1Atyi{XU~CW&lsBGc!=O7yAfy8h5j`e$&Fb(l+&Ftq+B=6vpf7XlZE~#A#b_4 z`7(@Ifuy=EEXvLHBEFsL&2>`YYQ&RoF?(f)HhVG2o_o?v9dk@HCC^rNppHXM#lE_A0)H{g}mu46a7-}>_zXN zp7&!)ch2p3bG%HBsg==xw8~#4!+4!kiU1_OD1EBQ8VR{O8?9zCrNC6xM&A;9Ydh+f zC_I+`L$aXi|3vHZysIA6Fs~@7nG|aPg6%T;7`dP@%N{s$bz;mh=M>WQQHU9x5YRvp z-_gqj8kBK-##z&$P!L4g)B|RW|342Aur6FY? z2Tabb!;jFT(WDvQMl(2x5%W4sNd;Q?Y_IbYy5kA)6*5n?AcD7{%j>&RaSqa?e-uXj zPC?gZX+EsyXGtN*w5vIxV;r@7@YKR`xi?d)ytpBF<^cv_rvZJ^={t~0^6El53j9N< z<>w|1J9W5=3d#gf;VKNp)0?)$J8rfq7A)2q5s9YOIn?MSUVwCRZ?~0>=;8f(u%O3+ zK@`>SCax<5&qj4td~lICXV+2Q%wV0PD}T=HP)XX&abBXhHTILZ zD;guONqtl}($`$D0Qa?UrLy4)L-a0kDkG%>j6~JU z)R9j)byTXkoqRc(4gFs&z{rytp#Yo_PNQ_l!%;a@d5;y|Pub6=R!f3d+26_*VKZeB zHg+@{ZMW1eqh40$#fz#M?WO-fF%^+dk|zv5+k%;gTIpeOy{9{0%~_iwxd2@G$cQGO z@@fD4Mf%`dXV13tv zZ4u1=?m2emnXOKTAha$2URf@;>*2hBY?Pt2^D(Y7*64b*PBF0m{;z=%F3s^aq0@pk zNP%;ED~4NE&tC7%Qh;~m6g#EXl;Pt6@ZM-UE)`sW29N3O1w(Giro;A!+mlk1CSjgT zD-Da3ToXsIDo|VWCmv&OTxKlQ>~{6H%)EaWw#sk5^jVFb|GS2~55+tdZe&f`B~mgD z6fpcgLl*VC=vmJ8SX}yE(KY=b9wysVDgVvOfzKph$3u-ilZ7|hkWL~*<>ZuoKSLFQ*CF^?FJxlgT!@w`iIA zA3wb>QQ1?x25hFgo=doq6wctwtXZ2iaEa-dsQhH=V}%-WH@m`(6jhMv(+6^*H4aDrvcR_61FQK#rFAlNuk4C4K0QcQyuI6 ztbIn;@c3WtNZt>S#JJn`N6b&`7IHWB%Qoy@dX^4EJ(%qh9k$B>&Cvi&&Zl`!MeE^N zJah(07W>rkU+gxPvLD@ItLU2PRBPGMQ^{(<6fS#eJE*nVGPSAdJ!1;{Avl`$E+@eZ zg$%DhW;p3xzPCkfTa-732$;fcONdeDc$#AL6(V4JIG{yJ$!@?8My=PrvR1d8&kTKJ zk9xaaiV{(L#T)p69Oskwh11KnhbSX>xpogTq4$E2+2@6}!}NGtJfc(npN~gD&*r~i zz2sZsK^IYFM7ACK{f7K*mCh~BRLzb@;#%N%a<&SC*#w1w9VnLfeLLRVmv0T&({iw4 zwOgxKzjAtipWInMUdNt@(AH;rdA;;$sR5N;F|El>$HcV0d*rcvV4p0-Ci|y|y;!j{ zHy92{UA}xSy{*S<>P5zG8gXn*WA$e*Zg4X=9I;x0L3Jf%^-1ALjf*y?!H5K(#3v@m z$0T8bX@SR@B@=ZQ0r?Wd-p}ec-FI$K7xW%%!Vl8H8V!1ZGTB^>qse~HJ7F*|d8gI? z1Vg`z1Vlw4O~&UB$yQfr+1M}(#pA?E|3wPrhQA$w!;cs1#M<%WKh5TvCAYR$ha*%K ze47_LjX|K_AF;uhe_E5<2z@#ct^0xwAHih-9#Sc(smb|smI7DUcEPXnr)E7Oh&Lz|38zRJ;*)d)gi+x2b;o=oHzrW*-M)4A=Q zp%A40?R%Kn97z3j==N$EN%)-fYNafQ7rR5wIq%MJy;HZiW>?x}q8yYsmU}65)-qEf z8b=DzT@C!+;L&B)T$ulcG9QN(dod93MF0jJQEB2sNZ3QL6{``BPsjU?St)D}Y zxk#j>r4ZTg;I$^A-zfA~3)O5cuFRZ301I6qAs|EhIg1Tf(MRWLJ)H5$`%;x=&@h2l zm8ScsTntGq|I0r5hWlR3Z#4*$w`+3glqe!3asIF3DVFiwSSR$;M7 zn>2ITOZl%4JJA&{j|)Vvo7|PhWcY8E7v}A&t=}&v>SlvS^EH6ncV4cfZgv|`usf%_ zz%(p=(u~#5bPg`uPuS%K-r5wF(r24n^kHo zg}ogYiC4*x8iB_y$+A$lVSlI~DBb03$#5)*n!Y52lEB8thiN=g75W@|aX2oB5ld!9v8!eH?T^9>h#p3gNDRvn@IFbNig$`&c;M^vCWZIb<4dtFU(A zDvdkFss+{GcChS|0rS~6QYIqIfB-NRnv)}e0K1sW=($A4XOlxEF#EjuvMAKKPOHjO zp81e<*)0E!cPY<2%zm70Y2_sNpY`Av_cIHs?z3kqH5y=1IkZ_#0 z&C2i?P;^Al1fz6;o7*wl06!5?h=Sm6n*m8e_ZK)0C0nAEr}{1S#MPaTYZU$Qu~H6c z`(c&;IjZ^o*NJGqf&_RV^VY?6x_I1_s;TbDBCgSuKY9Yd>l_cHOy3TN#5QfINv*WlWPIOz{D5e14ziBTH;ClB4of_O+d z+NS4|n7xqB!yC`$b2h{CMIRcGGT3NXl;P7;D6%oY1T)>9su1vTvfsQXLC|zQI*^y6 zC=m%ie5%i4pGNxW=$OHNv_{4eA43bbF%QIa$MJsYJ>8jXq}>yH3My;?Qdc!EEmY%y}i9brYeWm+7%Gt0F0=>is+G6Hl)DZ43XnV zARQkBW5;#iT*SYS@M|nw$EW1bWnmukp_K|>sar;L%zn9EZ`x|Krb)l^Q3Y6}XVJY) zeyvpjkyY($Fzo;zi*d$87Qv@p%$0Whe)L-cxejpbz%h;FX9XoBLmhsFJph&p$(hVI zf^Y(zi4{WS11?1?2nno>H1(HKl?gNGXwHZ6iz+=xvElz!&T|HX;UCj*%7Kc88a!j$ zxr2_4bOperpVEZ8{He?tgRAo(&;=_mBVfQ6HRf=LRyym=bEwuBc%^(M(0%wmx8@9zE@h0J&!w`LPg zf)yp2H#rkU=Ph=aG|#nHAs6U+ul+E_!Z1| z-}xs$jKB<*#~0PfVW_u4X&H~hpQk!OTJWD}?WTiGJ}Wu6p=iPgE@b-TzVNU^R#?%# zP*r^9qGGOKyM=`y$YYuBN_2pbH+E_`0dtTK0PVGBoj(b<1xv^UB?dj48%+zOxd^CD zlMVkT`JB#K2%Sn;kV^t&WQ{147Zm4qLQAe{=jXE^gl z28S+m@gYLLcSS{@$V>eFQ}-7>4h~MFsNnX7^So@NLZTxg`6#Wp%X;NE`ff-@Vxbsa zk%=!`^9tagRd*>A>E{?yNKE2xSp-3|G{q^MHF0|U_xZg8S*h# zF%aPm7*!s!zaSl8K$H&f_Y(n%?7gzoXp}r4B?~-!NtNkQ2I9Tnc(z@A8tSjWo7Vz^ zH*h~B+!)GxMH9OmVg#P#x4cFcM-wA5j;W3x7lot{7is%|h(6f%(Y=!BdXiuOL^aBg zi_-jK@oG7)I?}U)C2{UlAWPiQ*?d>3JIs0ntD+TG+~aWDw;?lhNKk%_6bH#6W}qzs zM(fdy%#QM3704(f51#C&(zuk?|&smUrvQWV=qi3)wKa!oIJ=fnRHur1F%^p?v% z&AuNt;-4tGFCE~e=S63&xlydb+TEsF!c#O6q5kC>?owz~ilQ^q3Rr!VO7e0bQg2iU z+GG(r*=r>I4d}+jteDAv^sESka>R~4u&6l z)bwC!)ddH{?UMxv+3h6Or;-;K=)ejbTo2nm{e^#Wc%Rq{+2|+vGx6hlb2h{w{vhG$ z2}`JW26MX~4!_(v_8=lWQ#yg5f&=KM4PFYQk52j^$)Sdq4`+T0%)S8!o@kW)j~ZP| z4vhO~h+LBL^X2FtUuFNx0lAXZ>f~?`3@b%>Ry1UL#7<4&jq3edmZU?J2%hI8&k7#h zVVjnkUf9{W;ZG4GJw2jsn{)5OvVM)q$3d$8?(@yw@zQTvF4j1XZ&1+C>iOiP`qQYL z8?IaE#FTy7+5M@W^?&M_Ep|m9#W4I&mH#!{ZtzoC#OzIDVf<7T;1GH{AEkm$1G{fS zMmSDbix)>VF$ct6=8fQJz`chDL}TY1xu>qofAUL_Ppros`tT3d2>lJoDB`_+TS}07 zzs%*tUTemkiz@n_Ot-W%O&-W8+HmWbUUVHGCEoac!quJ)V4oYFD1HV6yA(tA#3=*t zBuklVHGrYA%!*AX#hd;SX^cx+sSpVLi6uBtsGA-SKk7+7guL+`t$b! zmBD3SKAmL|ORfp$E5Qri%VQjIi0RegjAgmI(c40B>pnCfrLYMFa+2rO^F~a1a|#Dx z%zR-9R7TvvQW1-41i9t){XQCv5Y3M!XJ+h5LGdnMM!=Ns7IS2#lW(DjxE0#07IPv) zk1Z-E=c3o6#6k)X`c|djMQEtsN&F#mV1D)%i=l3ZC(TF5^W8we!NDaRC7Qu4?>}8E zr{3xe+YOg+z!Gr8N55UQ%cnp2d^{{ikQM{qK$^TnekKCDT{~T71*t6@*cA_w*}XcS z9I0^A6X~qvcaj!=J3PiDG&?3FAwrNUNQiK>&){d&KK$=f;hR%vTCS#Ug>qX22FJJP zyEbLvknY6A2@$9P% zCEyUVQ+PXWPc8-VAJGB8ja2kc!+mO(n0$G1tViNW14wW%HTvGAbO6(2AJ!-z4NXU) zy$T{x)(YeyJpGW$X_Z$(lZ;Xs8aj|d9I1$yDkEs7pWBGdcTKv~l=mFjqZbe(ssO%A zRe)g~Z{8D<$)*ZkIY5K9<V@?lRQ*&LK^*{5W3nwJGt~&0nkNCedNB7dzZ%av_GpS5>x@WoGv@|@?g%A{=LWY)WlNo_ye-V4S@5#bU45sk$cGSzluY9 z*PgAMXtm$AT=Z#2r{X9+YW zy;f0l$CMbwygk~H^`A?>AT+xAK`b{0*fj{5`@_bE@Y?Ddel3BjwvD&$Ik9u_s7L-+LyFl$uxv@fQH7*`(i0nu^1b9HqEPxvp(B9Nbt z&vqwBD-8gN=zeZPtBMs9#Z1xujaI*qrA&>kQrS=W-FF~t(?Z9L3Kj~OX$Oeu^Mg2O zZ!YAyYwae9b-29?SR6U&5jkZA2Jb8WrB1U*AW4siKt)(&SlZxXk?U=a8TGPS3IGEd zXAulvJ6!*D4ZN_!2zVaG1||16#+6jOq)}GD7ODa&lUcS%xSNV=b1t`8!F2c zmn)k0X;MflgkmuMAC+P@bNqR8vXS0Ijm`xCE4q11POso$)Ht?!14l6sKD`^$g0wMQ3 zMKlH=#xfX`c#pQH>w&0Zr9F#N+oON`q%XDW_T?T8!;nA3`o(H;xy8FL%6g9duaMVe z+E3;?2qfEI4$Y!*{fP4AKqEfU5+(--DVs=08G^qzkCw|QTj%Hl;s;z#0n8|o!fZN) zBMi0D=1g5Ao1??sri#aMBYJj^>SdATpt4Sp;q3l}ZbwBk09%!84x_>BYf+C6r6VxU z5U>}k=zw}&7pZlHAwg~#W@e`6_T(iM${noVNu1c!Pj<6unb2SGXF=BA0vcqK`^$OQ-|?D+G+7z>wJ+2(v*<9td+L zlygqy0RLxCgRTOZ2^k`2Sq@sft^%Gpp2(js_iqGFJ1|5t#VfBP>IumQ5YyuKk_!K> zvv*qOKcN%zkKQGZGAe;yZShC<14%#$k-*VQwHQ>8>x09OHnQedXoiJ7VS~g9BCp}4 z4!{oh1=ofi;p#Qn0>X)iH8hoH$u@@)qu)=LL2oe%%8v~m5VjI%fHC1WInHAD(V9L@u>v~4aa9zY^DM9k$AYv!JPt}UJ7(j z=t$KQ2`vMB62L*+uwBzs_NMAboMBt3Rx40?9!_1=BSb5mM8auNrO_zSipS~lhs@60 z#{0BF6=Yzvpri&fZ&zPy`}gP$-rnYU06%ESfGh zj>p$~JiBB|&7<2Il9EPKo+kt?!jF={Bu|a5?T@giY^uRf?50y+AB5GbSw2Cu(PI_^nX{j!n z#?LMpU%!#iMpC+b)~eZTBLPvir=Z)_HdgjL5Kb7<^T2iB?k#>MZ%(jWMx6C00R^*C z{3q-~JS0gi2fFI|1N+_VpK+nq-lyh{$r^P;#)&f*0mhdIw3x$xlf%l3X7WNv7S2N$ zxgMWUzN&%sJJ3%gwL_V@~ndU`{nIsum&>h!3Wl9|iAM#~hc8 zArE9^ZVHSBR4*(KLjic%#X!G|E0^Tn|kVe z#=QRWPck;C6_?OkQGOyeCF9u+Ky3@9ixpZhb@j5t^8hzO2{rWgiOy(_*GBG89MK~q zHaWqkI)t(OKS>TaMLt|$mdx^_QmPN5GTEa&x{jJdGPPPVoI<7?NM|IWGJ1KiGLPi7 zLLG5yXW6p^L1i|sT`IK2TTwf?TR9qF1)XHd@cF%5e$(xE<~(z!VaN@Rg+N!pO3Zny z70;g$(OT$GVu}M=s7HqB$%Hw`eX9}uPp_TynkTCi1 zMt% z!Mh<703M#NP}pPS?mI4<>(qcTM!M9N0%0j75zu9ShpS=4#1M&Y2b^)H+5t5#p4)0z z1$`0veK@hVPx^G=>27GzJLsF);BG>8Plk^NepuQA_~cn257SBFRaD`Q+QtI;Ty8nO zz(Po#v@;Y^y_1hzs6ENs1yu`ZB`Md zLJ-8Lfi;#=8_jHwk~2QNm^3j~l_x@E-N*Uvj3wgBH8+ zx}#zeQVK<&UM&Ur2>?-A1XvS_8L`9^`TBB-;%(ocbD2$j!O|yrq+CY6>*)p%?k4u8 z-h;#*f+RM1Ctp(tju00u`FW3tC`&n1b*> zfrl9-m=c}^6uvlO-sAZ)wPOnFmRmlNoIt{)e&WLPr;h z<0EOMHwT#leF+81Hs^n7+4M%;eoeXgrkXex^PQ(1Vl)By!ZsQM%6cv-2*o;9NyriVUtB{f+-{RupV}x9U;Y}|+p~8GBeI>Wl1-+)7$OMt( zCOl#1SxHHwg`RN~G}Ou}z%SU|tyc8VaT{y16O)1@KCPR*#=yvl>Ec{!-mqPeV+ey^ z#2NB=cHXmP=A%!r`^#ewg663yZo<70*Bs=5VfAg%$7 zF8^J=HLLj+~WQLjXbW{8_FsG9c=v!HaADwGTG~`k;&1)Ib-UU z22;f4vNgLsAu?Wc+&#>+KLkBFq6Cc+w&|HAE_Yp4h$M8n6TFdRK;Lti7mio_(^nos za|E$zgPs4%nQeG2BD6VLXIR6~fzsO;qrrFPW_Us`k%^ftFiKlZ_|gIv<3)bD+_%CH zpI(ozoVFn8tV7aZIe2VFs>vP0? zy56>pIm-R}d=~`oYPwfkY6@Cm6)5D0;eWVz$Uth5uFTcsfrMVo&;3F>166=%ahL52 zQ?urK$AazsG0{LyTH6SV@Sn48t3@8QT4L2u4enB$22-iaj=zHNeYD>59duQoBJo*u zTAw}~mpH+(Pac1x;si?4VueZbenuWHJP_yqdx=|TGu8E*n6MHO5t$=G44a|1c^shx z;pNRYaG^S6=Est@Ce?!4NtyOsofU(p2;eP-l=7&;rkEUDdhliwDYAbF%Vyk{7Ey;z3 zCk~>x6Q)2o#%GBJ(rajXC+~EP=?mY0>S$jK(w^x2HfO)Fj#;o!zE}BSb`0qH{_-^D z5Kp&%Jxnp|b9)X4RwpZ=0{;gT`J1)s&D)(teV9JYX1(=zv;IOORX$aCA{y)Tl+B3( z3@nm>f^KDaxnzPejFfaP({^!QeLA zp<7l})3JIR3aP3K6Yu~5GcQK$l~D0o7|Y}AG!9`CMJJV-i{>3~d>&>4MD)}W_QBp5NY3P>q5ET=oz(SX4K<#e| z$CG>gjJRr%Q%4hd@iwDBlSK8N3^L6!f_4Kw5f5?0#tlOB-daX49j<|9-v$_jewL3P zfQAd@|75mm=W@!HfLc{(fPO&z&ldPphtw@Fy6g~ojCLq_w0*kHB&gKB$8{2m&;%eV zcMW8fYE7B*2!mQ=S0O7an1Mkd{X!wOw`d6-2Q$i9kFcJ96vq-@X3kH3lh%VJqWOmy zB*h+UbrN(N3#W${AGiK($)+)0k3!Bxo=9LgJPb7;Pyty~(93%+O+PS(QGAUDHrC+B zluhN>H{*!5)3)aqXZVDvfc%G+2SXep&diXeG4nsZ4K|q1IcjW|O8oKa{aOOgnfGJ% zLwy}WfW=u#m+G%lNL69P`s?H`O@+&P==@gGUj9Frb$3E%h{8jP_VQ;%y1tM;SeRvQ zV%*?g=!JZudDRp^ckNU$2Pox1$Ldww<^u|-7=#lTjYwlBEb8z{8H7RRRzxq;qxuD{PE2)Qei)}ix z&n7X8-wTeKJzT%_PB4XXwO@W^!VS#X{a)R{A(2c`Jn#?F!~Uo z$jxDQJkm{{UkZ;Gu=(n-^VIU#t^96`f@Ddw6YYhr`enyqi~vltmi2aJR2phZA@=yy z>c&IEWi~xjR?XU%Is?iteP9XG9pn#<0vbOP7TQr_zHm&`+*r->sqyLCNd&j;{UYnt zVaN300WTmWXW6nH+&SJQ7z_aUrwLZYDc%m`5CHOP}SQX=1m_e-%G-{(&OhH$L0-8B?DNTtjaU^ z-p0&%B~D~+HyVdoXyjBH&&w(#)tm@8e2KlS+g_aoYF=TyEgrrW&dZM$?r$9B=i>1q zLHaz@% z>S*$lE@fXFhRBeK3Xn^_rJIks){XOx8rxyqjTqJsGj-PianVsbsQ#L%^ z2QHbHGs=^X3z{IRBgP&cpl7X7CKzu{VO>7=FBfKD>2Duj?iN3}ybbFMgGh@$GaeXQ zxXe&i&#AsK?`K240)&Z;-n*GD*k8W^*5fOs3yt`%zdDCM14%u%`QxwChL4qCr!TTH zY3^@>emGMYD}ZIb2lG&oXrqlyOJv&5Cjy%jQk7w{o7psLoqNk=EIs|w;iGSVtWL?B z-ToBAqYmJe*HKh(*>bux`w#M+(`Njh7oNyr1187uou%7!UHqQ)OCi(@->>@NDrrv3 z?JJr)I_dgTpHTJWt&Nl7vNQtx%2`*8mbDL;>l^7O+SfnoDQ4DQ@EwZN6MmlYUtJW>dH?W}6%x!qmZLZ2%8Tl(EA! zcC2X`08%-tcT{^h^Ddx@LteQVN|Ogr0KK)SR+Ha?U7VQ(Q+7{I#uI!Afv(qQxbCNm zx5tv9YPbuG(vMO-Q2)IWDFFt7;_}BW54$-dTRRX%iKQ?~+8SW(vGAxl;p@D~t9tb} z3<85EQaz_gW!CTdYxn$?eLG}aIV|ei9gbIFT=hggLig&GS-q8x8xAA$t_|`2II<^a zYZEHt4&Jg0sdr!c=w0ij-%OMZET&c@xd^!R^Ew@U|QD=lT=bj$40w-HVVJj;V2f@@@@dq@Lb4I@1B zaZ}2#d~SOBif;~pchYL@L)+hBP!sFvI&aPYXg+n#O@CU-Vs!_=dU2Q*v~OqJAiJoH zf~dX{c0AvllzrVWT+pN#yY5`k`m%d+Z)VBvEXdh z0o9vM4_!2G4KKq)_ipbLl{T6opjWd?u^aSfU+eIfH6tWM@d8dQTTzi@W-D z-#17aj|O_tNOmhvc2z}a#wu@DE749kF3`8O1GUomwU=PMzBafiT281h)|=t$X{zhMJivCQ~4W^d<> z{r2e$;y*UI0VY8?D(34Vl5g*FF55l!NJ{$ z+#&95ztZjF4I|E^IE~GgQbfuVM|^YPN)bdv1ll$43bmv$9%ghE()?@0V8( zRMt(T;->^#dWuqAr6x$9Lr>wVI?QkArmY83oyR_!|i;7-%J7)@r&Lq3ZopeA9 zDK`{$&*L(N5M@W+obda|=@w*IhH>O&VD0YU1d3=bB;an89GECyWj)|*P*w_etRUtzn|6?8JzB!du`}jy|0A1)6oxF6Fxi2>p=OsWN?}u>Fn+}$}+2eY8u!Rk< z8qm_^T>+fs!)!^q1%Q| zbElBh40}$&wA-$)-fM)Y7W^g&i$AHFF>l_RQQ>^IvxUvP0pd`ci|q8I#Y<(0^*frb zTqrmNqT`g-4|BO1adp_YW^wnc;|HZQrQz#drM}&H`ITx-tHtWbakMGtTc@7%652|u z^Xkg=S&tC?2XyJF>a0|K$nF@V!|@%gq(OX)$c-$a3Sl}8(+i{aWg z(Db6@51m>CHbJ^R!D&*1jgL*YySs=yNr3Oa#=CK{yYb2f3pmL6-m?cmJA(fFc+!BHU-*;jezMKnL6^Ua z`l}o6P_q@g!D>me=dc#=k%REM6M?IjH`16&#6R!kC-=jgICQ`$s+}=r9+cb|i z0L}PvNdeo3(;d*?Nbqw^4pwIfq3s^<1|5Is+52WK^;|FhBxL)GOQ9euq+W0KvIO6c z#VA6!4nGlL_NA3#?J_7@R+gwE#FYrZY1zS;#f zv;n*$F(Rjq+9a_;>w?O5Qpu z<;R2@Jm!cxnuk}5m5-0}Ka~sduJ9L|u+Xp=Q2_zd7Y`)K2;eV{CgC@0a>3~cSj1Wa zadX8*(zt}Xi(A=4P}gLa&*tdti-jl5QyfS9rTw;6T|!k4>Y_ex7zX_%=;#s~VN+;n z+ikmxPb2o|#LyF(zN2d1e3dlcXnTyBKQ%tO?0c9Qyp*-SLD;W}#Ql_L=#|f?W4ON9 z;+T)*zkHBfyV}wpVZ2;iNJVew-!^M7J$BB_do}={J1m#V7yT)Y2>NRWz0mXGI%)5v zbn4}2)uo%EFytE}QwC@f=J{u7iGj3n3rT5oUwzb2N4Q>X7d1pZ)XA_P^JEdjZW$qge9X$97NxCv{ zRg7;{UaP|(wM&Tz7`-DOaN`YwEvxx_&?Nsv+a}`Sfzyt@ezm5ZmOYeQrNT&ya;nGO zI({9E7Oc6})O2Rtod%b_{ScM@XM_|(p>OiCQ@ihNKu<+&9L}ag8Q;~}^Uhaq=jp(3 z;tMLvAN-!c&C-@2G#3!qG7}BGS}M~ zG*`m`-o^F?qK{qT34AE6r#-5PwnJ!G83*3qKHH)%(~Gz}%t?K$6*j5yOe0awa6Lli zK`=-d)BXQU@rVERmjTU1nIRR!d4xm_Hw8J`?KZ0J;Y*Z4sny&|KXmJ1J4y`?ipv^q z?QOP5h~#r`)Nn+5e?eC z7)gXdm@0(E4kn18hm?M(3x}$xOGytcI@7Y$N*oMi~uzdHQ0IyxqZ*;q(4eCb~}D18uB@(#4pFw z>NoFQ&ZDEOyaNUDr)xoCHDvyotkK8kdtsU$dS~xel(y7*D6)q?`H{b3WvYf!&C5aBlW{#S~56a zgsa$E(AhP02Ma`1RO5EQ|G1T7R8wPL6qhqLpOHK*CtY`k7nTW=e`$OiPMy=+EJwV& z!|=*gUWMg#T2mz1XvVWbn9nNnI_bCgPUQi*7>`bk`0nQ=txC$AY zc9tC-NQfs0Os-oADYo>%z0>9Kex4N)qMkSR;%>;-hKt&pElK%cey}ZiH08Oje?>pQ zb$@|l%83v2pbPnKh0jS`F@97E!61$_@9gSk=slYvz<$jDF!Q=&D^B+K4*@*j!NZSK&j^ zgcJzg8*cDlyyWqB$G z9l;F|-Afa#9hOETRHlqyA;9XaP265N^!HqgNV!1-KwiJb<*&>MciW-kjq{ToG-RBL z?}Q3*c{cQwM9CRAcYdgCi0t2@q9%Lx|AEZKv^!oWGMRRzu{&NVmH$zG zt#4w$Y7Y;GRjB(bCZZY+M%H#%ENG-3FSYG4;-mRF&7@Ps-EiZ=VM{#NE1RD^&QCsSRfi4zGKV>N<;TACd?)H9U+Y~0nHsi@ zkRA@pA8mi8B#vC+B*e5a$E1Kx2RC4e#T2du(Yw4eh;@IO&X1}HDX~R%@$vj{b5~7I z7&{da&EF3o{`Pl#J(^iN!fZH%4?Ua6)Z6200__xBZ;1h`dQ;RaJZDxcBWQex=BgLf z7nfs_5?^P2DHIq%iqT0xx~7}*~8BHqZlAj8A1N_l9OwoC!;#tk+BE(^7jzfF%a)CNINi?4&2!M z+=KZG76cqPfNu&B@(3wt=>J{*Ps39}JrNMvPDWOCmj7+$D?sqlyzRpz_y4zpB0{vg zI}m5Ww}V3O7_Iwxhu;4@*x&uh(PkNJWEOgZoBDf0wA^K`%(QLRPM6f2^I7#S6zJHo zYJQxM+w(1)a$Gn2mEo23(Dtm`{9ELUvb5|Sg!r4T>Whwmj7;QB;95%aO|m-Xi$mU% zJahg=BE>FyK8`MF0-x6fP@UGqcErrf4rhBur{2PE6I9XZvwohxxvj9+$+Nb< z4!U}J$lOu-?O#&*UG#-v_m05k@ldjna_}j+wN>KyW`hCph25Cd#oeVH`f}eqU*G-y zd$cBG`m{Z(`(G*`yGKmR(ePu}bh^9q!y(;7=5)1xeSVyYch1IXSZeKU)eFk~yJUoE zOW2G=ZZq4oTCV9?>M^FqXts3y-#e~&l5Q^x$q zTE8yyE3d;rXlBEi5=evfv{ci!b<&3RZq@;lG=vcd$xc%q2zE5V_)JyZSE#P$hlZk>o$3bEmZ(C+t zW*Tp6)1_WL`{~8y?Q5?2{WvL`yDO_JgO>{Up0dv zH+E$^@cYcgU#qny7=A#I(etuXLzbckM|RWY!{vh$TeJ1pc4BwoJmaITMz9TvS3}fA z%X-v#?^f5v?&s^zul()O0jioW$nhzX{*k6e8@W5C^OE_bDd^wfruIouED@B#oI$A7y<0lhx0Z`AmJuc8m` zkZ0-l=~WvFz#}=`C2v-y}p4U=wy_%^BX7=qm&cmzx}fe0pA0XhC6)qJlz= z(I~RjR)@MWd>clxesBZ^UGxt$dvA=oT1ZSRbT8s`Jt*=hg@yViXm2%olD#z{+r33@ z=y&kJU^vG1rCZ%U>(x3iPS>k})A?c~64m3PQfk&s<=|OV+`r)@Q$xJ>$(nmsH*x*q zFfBec(IO%uWgKbi-Jzk73l-`xm72PFffY6=TPNn-B&}Rgb-~s_S>)sGHIdCtmo%Rh z=!^;~RqFNN5b!vBg%U{%)k>ub1n32aQ9AmE(*+4wz{%_YC@3g4$0JxH`|da8Y8~84 zjYfggjWUV+bMngyDPPnM&cNnA6Rkrg zJ~}3cQ^~fJ4n?*%@Z^y5s&UHe9WDKH1$_Z}T9UZ5^x!|?hy#xkB`w!Y=UllP72djk z`X8_$L192a`m1%uSt<-~gAeILnm zx_EHd%yKSDN{I@-3)r;+N@jI^t1s?EJ$FXl#-9-p5uooQ*6U4_?Uu_`6zX*a@yi-W zH<6dG=rw@vuRlq?gAo|zfj_FV7dBdLOfya7qaB^6W0fT%FlmM&D_Gt?3i0lhb>=HAgqV*;fLPA3;Jd((b`3nTPv_;|tj!_6?Dy;-Z{ciue z@CS=N8{7|v$nIoDU#Uz>Jj&y|WQn7Evx4Qkmc^?`?{MT8L)R-$1dYSxqNI~)wczu- zx*MJHb)?CAQCXEz$N6`m^ni4@w(1M2%i07pe_1RhA6mU(^m zzSv4MF6Tn1ceBlA9rs&>4bsD++zP=87A!uG)?aw-I48F$dH04EuRif&L5HPCm$L<^ zADR(E$!W>1vZlvD$}W4g@(S0w+O3UQqK`@z^(fs!X|j z=ASUk-^H=hv7H?~G?fqrmst_MpA`Av(E?oYn7Ja7(W=Yo+#q-1Aq{z(4h1QnDk6sl z95pnQBL&-E8s)AtBbdBOfz^Gr{o^O~`~3a;EVzVpDyESk(XJDl<70u_3in5o1Xq@! zKIWe^ADjDrn9o3}+k6q>)KZ;Hu^kdAf&Dj+P$oxsL){^gayuSKLDjF|AY#5>&J~m~C{f)a{iU#)x2!KlRrqaN4iDl~*`nU0 zE=oXe52peDk?qi^Rh$CG+lm2J#UJuVq$H#zZ`Jn2)|JIp%fjkBi~$GB7UdYP`FDNn zMpcb_dyLULvlUvc$mh$|s=A3@)pXFDyx?n1*5`iYpOKUtkTo_6VTS5;Qms0^#v2{( zjyY0iZAen$=QvKT&>ohN0|P>f1WKTBi-qREGL`YjTIs3KW!OPnwPl|#`!O#+Orc&v zgLH*LiTz#(e7UtEhuH4!uQwRmuGi#=&MYO}_`jA*1KnSbbPpG+lA%;4N^*k<^A3J}3pcwjnFy z{|+e#fQX|lj|3G~&;N(0QI3u?cZ;9Kj5OHSU;93SRBXWS0;V|EU?}*uZo(TKGjB5- z5rFOSsJc2y)O9#MSf z-`9Ag?w|xdiIvK!BEMpItYvIlBV;88!trl&RcagIiL1quMqc|PIbr))o7!?t5q~ral{MYMt07cf! zVQk5KRwm&g&7{SNftJJ?H`>M4xiEZLJMG#EDq;7$kWY;EW+FI zsMo9Z*ByZ@T5XPeo6Rpf|-}+)iwT?h3m_VYvJ8DE6G|F~xU%OJ?V}ocYbX19g_*J&kVZE=L zW;>s^fU5^*u`HjZTPzOhx1sNxP=s|%fCh`YHGGWE-6(k(_GBhI%72)z{=zb{P_J2Q z-^UzgGsUHvFU$0TVY_r2nS*?Zm0^6&%WZ&eFtI3ndC)YEzp=v-*ZdPHzB48ZL}AM~ z;jQQMrEnDX-vuIxCdZ=?+@VZ%#|4hiAEtG#`Fs&oXZQEl?{d{@6(2MzCAoRxv>&-< zVQ}DN((yzXBlV%WBZSBEMb(efJ5}g{7WzN$fWNpukO*qF-@Ysw5i>TK5GF>hhYnx` zAU8jgr$nDQ_|U>Fc>m+`cZd5@GgEY@ArW|Rpgkeh711e8p7uo0+g>+Fe7u>CVYwXvkvKzKEL$fw1X=Kt% z-J7RKGOMQ7zOCTST#u;hRw9H33nJvw@sH6;>2%>HOmn=8IGCZOnt(qI)v8)dAf`)2 zH_0$%o6)T2X?Ts`n$dp7k8+_fyGFfW3Ul2V&7!Ej@ay-V^>tcn$bu~dYxqGoDdnC23 zK5oWjSA&`@$JuxWZLAE9NhWyIj7v)5w@L*b_fG<7q1518GMId-y(3c_>eSv$!enm) zZfXjYnBM!<5pXy!9WvkKGR`xdE_?Uy2aQmd4ybLvpSC+z(+HNkaWY+#Nm%7pMqfT8 z!#ll=(9Bp_aeTRIcbCBWVM3PAJ!JZPaJUwgx0`X2!I}=ne$c}L#x|2eqeV%5AN>vo z85gdr^v3q&^o0!kon8v#8a%+F@p(c6yT21pfw0J;VpR1F09w9@m71|+{R)JPcL`oj z-Pr%?=636oVge#eL7gG;b$;fMb8y4k`u^Jf@9zmnE$A2dCBW& z6npVR&YDy?7C8f<&RG&b0FSoFt1Z}KpgSr{WTQ8S!7*iv20zBob~u}M>r|5C#26{o zVr$L&ve%+X{M+0~1WI_U^QlZ5B>^+Xs~qAOt83-~Uz;BQZ2)w>`R{f!;+{HVtn(NX zhw^dVW|${nuP02Xndk~wW-oFimpLmvk_xC2pk!XCvIbKYJlo&~wcSoEi_L$aCBdf8 zvoBR5~3W9PA-e+yQaj zt&ZJE@+t8aoQNT(b&S|_Yc8;-MNvK`>ZkgB%t%g={rF%33XE*5l(NOLIRfIdY>J=( z@^@!j6k82ged&#{rIM6V&<1(9N_j*?Lc~$~*odp#K=OzbC0PPfq+5YF^Cp|ne8?&j zU*Nd5o{)ninPt*=UrOLvr|pCJx6M1Qr+X-LkJPlZTQtQD6?5SX=TTKx7Y2pNR2xd2 z7zk@0wN>+SOEok%#b-t3D2q<&o{rR(VmannT<*y2u9phaPKN7St&S-g4a2Sgk^73* zDG44%SU6F-k!DW(y(z9axl;K{tvd-p_FOdF;92Ix;#cZA$Qmp4A&-La$g{ei5qZCY z+at4u?dzvjx{%VQ1XO%PAsy~8q%4jZ9E=tiCF*=4LmmTod%rW}D(_B$;5oX2wJp>OvrGHypBL%QM!}J?woxJAv8ayUu$ZM z>r#1BTe`X{va);ZC6~<>04p^!@BN1(_Tuy!v|L7$gTUBBG8TZy*S0gVLj@-f>yKhg zGJ=*9?%U35y2lKqNqh){F|6cOQZrXuesNq@KTIFY5gw9*pRKt% zpOPJ3xE!!JR#}QA!?6DB@@myQojJXUts)c*K3SG(lF7mITH+l8F83D@dIb`ZT3^Xk&o+k(3 za=OG?qfOonr#G&2+va369gVBvHFUFP*gK%aG*qPCWOb;dIHOipn-vCMHssD>(nqqW zu=05J%Y_tH_A}wU8m~#k@P1bGjdMy@RG83G3WgBYWu09VjXWJnxbuMou z_%#C!6-OPB@ux8ll1@nVVpBLn=l%NXrpkUwO~w%|#%|bZxb0TBScx8kH1NaaZ!}e{ zypEqb48q|MMm9xB%^Xscb^+3iv%oU2ikr&o=IaT%QvP2%9q;C@+d0K(Kvhkotk267{_70O{A`D5is@v=;t?tAhjVvb#@c3$ zfC?HukJ||DfGXYwa0i!Bk}F*=cV>l}YN-mEb%FhvV<$I=$?Z>g(q`UKA>Wvh4Nq{r z%Y`06-t@`l{Q=1qrdM(^ACwPE4b!k zPG_Q6L^0ScdJw3rTL^AKt+o$uFMhl;6-}_y;TjK*Kus`rpr|dz(tYf9Gol_wlh;#@ zqVa8QR;@ALVRqoB3VM3#@T&o{gj}*Q*Ya8xfvnuk?G(;_^(3I+d3|S(hSd`L4c`%HThpSZ-a-%JqB&)ozF!n2SMp#3*X;Ovl4smX^s1P(cmr$Ts(iln8-W|8glVGX6EaxN&nd}>%~xUl*V$H|1_^}PTe*~)+*`y zy7y!~#yUiZ@Nu(S1!P0BPsp@U$fsDYLh~1{MyrUXWit}y&-dpwpxj&xt>*(x{FmC+ zAHyYxN)ica`9s+Z5sOYPcXslgbYf&8Bo@fedKC^!up_4CSUVoeY9$@)Y_{Rg7OocG zuL_~{W?NMavT63B(x0_QV?zYs!XlLr-1L}c^I)1k@8dxwxC%?)E}6i6vU;dKZ>nUS z%3IF)8`_qPnht~fHXhtE8*3PE>o=}JN`_m(V)J$5S*qgQ?&QgXxn=(AGTW?n`zphN zeM4oxyqsBA<0O~bJf(UgRbPSCbOfIyMq!v}Q;|l031fi+c`-Oy@m>dH`rKp&5%+5A zr$lk#tK?cUNKPJIGRy90EY@N5XIj%=Z%?m%fcbuZ+a$->n}lH{0vF!%mgn_g`*m0O z73wL0L?cUu=v(pf&JA_AweOI|v=h!{_HT7TJobg3oT#9Vd4jEF`qo*;k?K7^XL(a) zpCgwVES=xJb8iQ;*m0bFYgef5+XlE84rWL@XsGEA{o*jTnKjAb=07rV?J%AqzC?KL zE42fp-9xakRH4i=smmMlnn|a^@h=L|Wq)j!e=7YW6$fqlr>A6>w6+X`HUKS1tSS zjde+)3Rem2&Uk$M&y06y?{kuLrQ=lD9%qybWy+G2FiPNLve^}4Cqw5Z8gs?7>9Evf z)HI*Yn5tb$Y&=W>?7L}5&cyS~kL?L1ija1Ykx_waW(mq}!Lv>)u@5f9ZKkYv{R(Pk z9BW0KQAyE0E^kIJ=Ffi^7UHy+u|hBv=wodw5$V0D5q9^Q9s9v?635UC>qIa(H`mPJn=BZMpxx~8#u#4+mEcv{+)dxzGc-W zc}wj@=U|Am&#(7uOjeuBcJ4C{p$u!GX4^S~-?{DZhJ$I-PIQp!f@|rfS@71@%)Dz; zGV3O4a|M$ulW~xECnlZFad)bK2eY+EL8+FpkDrJ_DIDmKgZId-+n+%g0eA@_nFa%_ zj;qqR^c=W#34gY?4P;hcsH6Q~37>+#n_grUn+DVjT4IyWQnSseTSIHQ)5S_{S>J79 z6@LIYr7>Tzx+E%a@UFN{ChSXSo+7ORwqvCIfR`7!CAXN4NAzcg?4B81va=-{He z52fCWDQf7VF`Rb7>ns*R!&pP3pmy-aG!I5mg}w)~O2+hudqNCV z&7o|w?Aiy#{wmPL$ZGF7S6nn}KhjDW#li?EjIDj7<}PthTaQot@T6jI zJ+|d*`(~kpdnO7Wf_CrAg#Ym_+KmT2NMal~|;tpoY_a4GMJ(OIzHT zYw&zlyvsZb*0F5yC|bpTsxvmQhKDKBKZEbq`&Np#eAd0T?UtSM3YA2oclNd(MK)wo zhNIwk{NR`196@kLSlm3@L6(5PzOA%jk1z1f*)9dvQE~iE76g20(LaGfGK)#Rkf$X1 zRtIBhtYt^_4Q}rk4A*@l#1TA@it@Md%*(Z{Ch?$f-^H4#GmrB1u;}qh`%ceimEOu- zrh4hGgzr#r#jsFC5MagYY)Y1l*^Rlr`3a& zZzHwcAZxTrf$XG1l2m*Z-^E#O>^FfCF-*1-;2^7(fpVRr`8L7a!);Lb%(D%*SoS2Ht2zofi zSaQvilA$MwY1=TJOfN(SvG*fqpqX&!mQzb} zqSN{1R)Q6zYjaMyK1$2p88e@N13W3Qgh)E}8@?6&@9RjG^qQGpwQ+t^BQF~G-k`A2 z&tWO^%r3hGJ#_~UXuOf`NchVZb}1n$ftAM9tAuMhLc0`(L{_)*ft6x%zZw zeCXml@{%7;y7Zn(Hle_Kn=Zi6+)W6Hcs-?M!Ujnb@{% z+jicb=a2WSbSIGc-l7v@tEv#Vebu zjf+Q{_--Im4udW+bPBUPkEp^ zlZ0Bd^UK4P_q(-h%5Z1bNNt4qG1{Gi|44`cGK%o_mQ^xpBb1l1ey!onz*O_oylDQ}vz9?uY=~n3}2RNWTH=Rl2|o z0PxuDR^!f#zz$H&?A`NzW(qW;qJqQHvVcI!jl`6P?&!`t%i>iand-iOh+ z@U78g)^O)x4?DjQj@9$4CCbCwGaZl-5U%nuT*mC3!kqf;gDmAfI2FFj026CsYlM~= z=$_SbU(J1t;LMaM4NJm zRd=0)!;k9onU2CihuE7e`DRk9=={q>L@n3-CY&0Y?WgzXEEFgTwYw;?=QJv~Z{{2L zm6rqUBT#J3KsCpntW^Z9n_xtrd z?hY>lO%fG&3(QcmLYsy=={|ixGn{4D9T!aa%^ze>CxtPFyb0f?N6R_|pW9|`aW*qE zJ6(WxHz&4=!c})~{f$M3m+OG`wwKk}NqRxx_4)C$$D=fJ)yKo#t?Z<}r-%E;#`}Lx zfB*k+I`zlev=PcBv)4IbY}fNIdN$GRXal>c2Hg!kk-pR;_sCwUD_4q>WKw@-(A zwT5MT?)|L$^vaUY%vti~5>;L};}uYmza_F}7##;Y*QrU)w)gHtn z_=Y3r+vXYA!YOUIs9H4G~==-Y@(rSrks|C#YKV94kPkC-3HGv$% ze-d#HcBGb{$_Wl$|3>f5Pr#^e3+BXiAEczN`~*WhXQNPcLRqtLGjO#I^#g9(FXrP*eT3;K?LHk?^z+6c?AOI5aYC3*PFBGUiyj ze)%I!K?-skg{;~Hb%oFuSlgK!@NX08w<@3uBXaoEp0Qk0ZXp1Lgy%0a_@2vdTy*u! z;o^q?k>e-brt8YI>s6=FV)XRqJ07|3x90z-4RO>ht-Ur@Ci*-RSV)TVF8W5!L5$6l zDGejZF^IY4d&eNcX+6ociJ^E^u8EcdC&HH-o1@-NBI(0CuXFHX_Gc7NdyV*Chg9C1 zo@-v(S~~36&|-0kxlYHKu7Xr(M7c9|Pltz7UQ5_*{9ZI8P()pOiGS@b#&IL8FcRcn z?4R}zR%6?mP*&82ZPI_madn4rKwP|}A~5;S9|Ikr4AUjNcgo~(=R2U#i5%JuT0X(S6vt-gt=unQC5=*qp$wEL(?DJ;GMGY5Z)elZHHZB=G%Phsw zX}D5S!?qr6Cd@oSB%3hBq)JuXg2KYxr-nwf>oGdSj>;ObeeAYX5^eN|jWIk4KHvKQ zFIXrIzk{qFyATOg4JQl+#JP8@d2K&B8+qPsyuHyTW|-Y@sMhf+%x{xNV=pTt;wUGy zH@$+XUwL*T(rU1QlfV(I2lcmlas@TZ8CP2q@gk2?>gpHGuvy({dv#AU@3Fe>?m6GK zIbU|OiDG&gx9=QPRQs*m?wGYJf**VKZsD=Ug$24WnBp0QGwP6p#10hRr-SD7=bfM$ z^hxT5kk=36J!)+%q)WDftI_FH>JceHBfcXIT9@Tjy2<`duM1E=^*wg8|#BG0Acba_4chr8p8E*E*%d*lB*n`!>mQT z{^dd9x^A#~Yt|&cUAD)<5ZK_t@Fq#`$(GGv6#W@c z!~GtB)A@ptHt-%rm66$%h$c71CV*ODn-=AD$>C?bep)=ci-bsU$C?^gRLZk!!|TTl zTn^(b+UUlDY}u~RV>TXd=&bhiL=X^k;b@7p49Lnd_hlv3-&q>ISmMez|JmX z7rjW?S}KxdGHJ2W$Nt5%7IMwX3c1)nOGZN&X;CV|CjoCTqKqK9$oNcOS~sav5)<(Ddq zBduTHsSo(!W*w^`uRp#RZd*ZyJF5itN;L8)M~n48O?j7gr3 za8OVN%r?wjPc*@W)Vu}r_J%Z9?#%XLeyY0w(TO&yY2qdLf)Z`Rx*rp|9hVuTWTw2?IcPu5oRGKEvBGrZhW>BUooKt;U{`Cu4KT z_XK{^0E-Gt6kVv)Mq7YEXtc3lr_w`vcq#$XYzLHx87Y7$l&ME-0Y7=3+GNx5scEVJ zdO%fp;Am4w25nE`4L+akNxl}4eieX(@JA(7M_G&lgL(JHWZwLZg+I(da8Ea!R9jt9%th zeoesAa?Pm8c_;o0m`%9{;lblaUK>M;2cTTwKzPwQ1mU4364~z+(O{~XB3FW+lJ$GG z@k6{Lg~cuBtcZE6PTe+b?AgRS&fd|iqdp~7^WCO0y1qolSECICc3zS3PkWt;!>K;p z=?f3EB&A*5Ff&I9?;G)v4y|c)0J|%uUDpR(3Z1gSd5guB=0patQbo;+;bz zTa{JKTQtd!%5vx8GNFXT#8lB|PZ?A!-`wxq!C^5Qvq_rc_4qDGO728`omgx@quL`o z@UcF35m)y+>95Y;=TY^fg3i=jsdY~}BQ~2>X_j?aa3e<*B;vtQj6~u$r*;o`d783| z7I_TAq`-O-EJyEpr*2C+uSSZo%~h^R&2rB-0)3H5+Mez?l7^l;C8} zH~XS=Aj*S)X;y8#i%pd?AZ{-#9oI!lN+9e|cEdFP5|SXcj4(8kjxvu4&v$&5(of{# zvfY_f_FZ#1vk%HhZQxZ!T6ATrsBflLa?aIx$# z`}yF8J{Kp{mlOU-Gj51zae<)@`!~kZ->94;{QvWt|HVIRk;GKV`Y4#K$5GPMIMI`l znS?7j#1Xoaz6L-_62QemviOOk(xl3^2m}X9Z%H_?L3lif9kZG0jQAEB{rb;U{ul8K zkM8TK266YbE2=UwfMCa)irSQ!!AFb5V90f$m#VjeN}FovbsYm_vj!$dx6L13mD zZRAfvD@+9I|033+*;A-P8kAkUW6XmvSwewReVPFrHh#73m7=LSJ>6*)5E5`(cOoI4 z_tb-gz0Z{4Xtb)(gGNU1jJ+x7vI2pU$jRqf<#}?wI8vzIT=~XN5q#s7~`WhA~u^-M5 z4ffB(tUVbF?dwCA{S%2wG+~@v(=3`w8`KO0gsE&c?nFP~-#FU(!&zWQxKBuJ@sGa( zvH?0#yxOiS&7=9mT}jN5{rBULs46=!<-167|Ji~hk$o9fYZ6xTotmVp`2kBN|GGrw+^#_ zQMZSTM0t^_ne0O5QzVV_IA8+<17rfUXy7`rH2QB2cw9S+72+q;{<)}EK@eKRN-YdM zbQ*DalH?Lvuo7$6yEgbK0Q9T@az1yM|BvhFrPx$J!2F4#NYuj*Cc7&iOPD%d&$|Y@jCyj|JX&zBD4w7BzetaOtwO zF<{1Wc;C@fH3?fEsv9yIuHCzw6^~}+68A{aOv0iqRVeK1AQfbSz<^O)jdsP0-i6#Q z9*nGYGuvFJV`$3$9U^R4a54Q6CF~Dt_=lypCI7kSao^+&^P`+xL2@LatnFs$M z&&tZL4^qa5evLJ_ircixVCFxNJuw#zkvHD#JK3+ZS8zQqt#MtQq}_y19oawsE!44M zUAFuU_Hr`HwU+XKs_da{2;3XnGQgN2CenDrk015?OXM_m^In-$9ZFu;0Y+ImIR=~) zj_B1}&BW$Hd*U)$Ov-ETc$E>}pb4WOSwjSmDjm$BV;h~-R~-kkuM^)Od4Lxv*@p5>(Yz?7;T!9|YTD)E-Xdb~8qD~{|NeQB zP_?U3oR^e)+eex5OD!)5YwHdWFYPRN=9j@x~p4?Yb*Fb#(F7d%>UEi;tIm z<(&eiGBvOUqtyOWW^Zr;k8etN1Tjw2htbB@g-O$`qvPhc=Gm);=PvlQ&%JEz~ zA9NX4jw|F#B(*l@XAQW^MZ}rf4lt%=N!?W#MTSXn9@6vI$Vg%@-?)0PHEMMGB;J9E29WIj~iWV6pOP zc@kAZH1@i}n3u~0{T}*xn0_Jdx$7feMGZvwW_ItAJgFRL^mZLMk`^3Hi=xa|+3*Wg z7Y%NJzTTI2Vv<_sni`dpP#ZnAX}sG9gbnf4T@|CZuX5~-;Rnu4 zG?8R#Iy6|yYf^aSe(JBo_qAa**%+o%BnVRk!{P||{9&>_k?YZ4aRp_GS^@bHqWp9h zv(oj0YiNm6cgR-3jh*i(`1*?g&Mb(ajs_@IX{SV~%oHivGumv=V$=T4;yL;K(#yUG zM~1oaynj0|6xxsl|H0wF-sHj#>2dzzxEo?ci@HSU_;pi7tc%+L|LD!M!S&vYkGEGq zF&FV+RtHv~0x)km^pnK#jP85VT)Huu(2Z$eIqg#GadY3I=GuQ&frF)E# zka_gi$if*cgD%2jT;H63ax3`JY)h)NL1PEV{^W{_8MLT%K}(Rdo-g_LW756MM@|Z8FGf!Vy(1p)9gnke~eSqT=rHkYOMGTr;^)l z64Nqq_A+`9E;U`aEDp+P={$>=Y0=-qwnTvk>8v9Yxg+*0vL)C>w{;3+mrx=B?ifkO zb_>Eq8vcM~3XWNTXF_)M`@9H%*;e-tXTA(QWS}}eW5J#-VQpu$lI8y9ehytPVGj${ z*IY%0wVfq4%+-OC$F=_hL_j=du=i)EADBj=f>SK%+WJj3oFf-@AkS`t90dzc&fR9 zHR(HBYh^e|d>ErQwvor<{T4wjfBO@(km)Evy)_yuJ}jjG1eMHx)C<*C*D z>!vH12KQt#JgT%YB18vT4D<1?G*Hd)1?lxAU*^~>icm(l%|r2}ggkgw5x|$fF-a_# zTIoF)73#$xc+q!#ry7i0M4c6_sQ+=xe5^ISA@FLbFgJRse_Uo12tD|5hXSzKbx?gp zn%UF^3JD6@Tfd+len9RodY!G^sWL^ePoq92JE<~o{KyA(e3aAIYl_Krpfh~jtl5R7 z=}C#){%gh4`3hD0Yfyb4Uw-p^x==e`_-)1Z7?bwn+sJjnajnR*IPsg=f`Udp`*AG{ z$$J53YFwL(w0mb`Bi-jxr+%y}cVX3Ux2k8?kX&}R{u0Ml{hozJ!JdKgSDN;;z(Z~Q zH(r1J!Js?k9cn8y9nZ6G0P4%}K_(}&L4cQw$gQ0+dG+r@h52A&0aq45Dk`dX(0H-q zT2*F2At50_T3T8`kjLi4shra%A#$*T;@7WVCm*$;Ha$MQ?oQ?rSZ}aEb6`Thxnv2I8qi`8j)EGx z7QI72l(uyDStHTJHywu-gQveW13lya^g#Odh;?0Jcc-)UWIzR@01|V&c{yXKpEiwt8$0s`+08n6z`D?>* z@Q|T<{qX>b!>Kf{aE}`=iS(X-uj$6dzdYIhv{*6;Lfv@rkqDFQ$x3hNeYKV(U}D;f z4#vI~f-F&0FD?^euzHI*}RC5i+enr6>p>1g7VO4fs^{tmBKyRS^M*<>*mi=q#= z)?)u;>3?+BR-AP9S2}Qp1PNZLWZ_m?CJ)o5_^o0>#qwyjhG5pq{}yNeRK=5Y*W-=X zr#%7(6b{ExKVrSVNvwFaPI1mUsJ*M)nbagabPhw4@6-!~TA``_w7F_}>a{I%Y63 zQXm!5_6;XPWy(~E-YL>Tu%{>?*^{T+*){cWrXs)aQ0wr}`g5zjUY!~AI|!*2 z(v@Z*KUh}Y=ksu{LEBkmCG#R7_3q^H;_gjjW3l=0pt{jpz%Wmu4r=5Kz)ayY8R_@+ z-H;X9dK;G1#9BuCSGqrt1cd^j(i(&lqJ$W8BuZDXCb~r!H8*+u)1~4Xj+Zmw#Z)Ls|VbM+ZSWx0d&&CX{=m)__N&Cp1@QIhSW9W>1o?t*yHfe z*&RRy@SS*|yx=uM)a#wPYEYaHWVbi*=<*bHye@c*y5Z)`p|H0rEqzkr^klGOd<0l0 zw6^`gZ=+RC%l8-NU57qp(rw9ByIW7byv-v;6BZ(fJaA}4=yf(i3;(2ded*N_nluhpW^qKrZqhYL z0ILAw>3s8#b+>~i{E|eJ6J4r^Q!P>bwx1*BmmHN7$eWF%>_Qz!K1TF;C#&muh7;` zwo@~b3?vdDEQ4QmH#}OFWx4}cVfSEs%TMlVOsjS(WqgxsuM~gjd_oSu$V+6ICAkC8 zcp9HGAh|;{8}rdd&*p(&YTpRNhg3Zyrci<#lihD=*Hlu6u6+-@S;lpgHZvQPu1=iIyuN=tzsHq7vrnd=U8%dL zi0gvkTv+ErpfYs&IDS!BAofWKhpl64?ZgX|J_Og+N0)B~ z0`EPJ3Zkn$gAa-HQ>A8N=UuO14i|fnj61r(E%S%@S#lOt(M^~J5Y7ESuLazMZ6wCi z^}UC#K6c*qEY~}9T$nrpbvVpL{;cDeCzkgrw<5jXLF8#gy)L6CU1K})qT`7VOhY&d zr=mLl@e!NA`Ht;gUx_AdWMMwNNW>bObMUK`X}z}GV?t#@r5hLQ9yLVAsUuk;kVW^; z4eQZ&t&1U~(jZ?&p`bh7EQ8jhs?K*gvmKPR=-0}MiY2QVE8NOHu`$g9k2`t}GFY=u zPiX(lXDr3>Hz*?dpAl?Vl{3ZgYRZKU9546nG8+mW8bWIZP&wZMM~Zct{g$x)%&gb` zqWn&yD!N9OCl;y%=LQol^{C71OgLm$=nS#zoVNjHh139btGk(Qrq4^#cfqBs=MVWrwuAY? zn}flmOp3aF5P#<(!W{uC;84xGce+VcTc_{_Ghn5HFFUizR(PZ=#y5k01Kd(Dm{^|1 z-ft>@QC^#kQZ+r9M(v!9_SNxJUfo z;+~E?MGoGb#bzVng^Mmw)J{0e<=#cDJm+)L|LUe!(xyJi@Hm-N= z2g!fU(Kdi@48+aXoM&piQL8Mbci%bEuM#}%#|B=x7d6O{=2sAVDsCvzrVh0{g{;6z z1Nk|BnGq9SaTj*;kLf=xwm+2~hbL37-20Rcvgngpanf8gLAGzEFt!21;UIB#LN%~y zK@FOY86{~ze~}OJtpbJ7^e3+Hoe>TqT7fbX=mvm;Gncv$`VP0upsHjg^6!)`{3D8y zo0s)7BQ}DD!1Yn#?sIYBKEZe#BM}UjZ&=A6)F|hDnMep%dp@*BLNE4n(RZwm87XZz zI3vCaxX-czdMVEc*k1S8Gn@Ep*V=`{i?;+vycSg0Os)_)Wt#&EIk}Wck6hY# zk<6RXTD!n5WsR^`93Y8xJ0-rV{f(iD>!Ew%0m%XIrf4Xug(go*Dj<4`&3rQghrx`? z%B<6m=*YLhDFdB~qBe*IHBBOPn5BP@_23VVR;mBcAmMndn%s5SQbwvq0z^`*kGk>o zj(8-?={V(ta_AgU^8Empz|9&g*2WtaF@&TFoWaAqk;w5Lq$J!|J}=B1=}xJ>;VS!& zJwvGBKR&-xyM$k36Vh^*~zr$zr2>nEStBLnxfW}m2l|~^c zk?^Xw)fkD)7pKZ*|rSXNnph2^Z?EDBAy-83I36*>(b#QFd(;4 z&r|Moe~!Di*{j+U=K6>y z3ayR>$r@D3TukAvc3fxKSv^lRC%yBfZC6&+P2AuPe}F2y<0>|%+UgxTgNFhWFN@vG z=k^H|mU51_#+%uS9cOKg7WTq>yIt;!dq<-5d9b41m6MgJd)g<$Gg| zBS!FqqQOTpWz$K2M{$f`Wm^EBZwk4`cEx$4!Gvo2nj3QKnPmjgwAO{rJ;!PX5T;Rn z#n(Pdz<+>=vc&mS+r-2GCNnNJO7KgA;X!~hF@Q7^GaW$9+~L}YpK-?ehBXIZ!-Gtd zlbu7D8O>Fj?9ToEt*gaYG-UIQ@n8|3IS+BaPgRbCU-DKD74|9Z8&e3!`-~$qA|kTn z$j4tELV(YZH;{aubQZ#+F>h}{Eu?f)HUnepvmET5lT5?D<=a5Kv;A_nLgZ7Zs7A9O z#ES%N#d_=xp^)66j#~09LMD<~$5_fcTQ`wTz0Ng?b=0-(2BSV$-qbFmGTnf;Ur}&F zT+rbTZ$*)GlzES0wQJ;uF(ICZ~plgyme}(u(M@}MR0;ro15pxR; zY;>!+YCAVchL0^iHM1``E(^9+@KHQkt_Q4>j81w|vlA2^3tmKrZ2|%x$3-DtHn>49 zUU;_)LSa8DA4XWt^oW7>TtOT@-JQ;E}-l zfQ*_dS_uBWMR=BHd4CCNyZS;kvi8X-&yWXIz`q+`rPoi-93{5dh`-ZKec8?FiXCd$ z(Hd*Tht&1g1$oezbC3M2c82co`b|G6f{k-^o5}6X{+X`t{T;2c#f+6s;*Ei60Fw%$ zL#~RYxw@c${~>!zq_4si8qG?Btn{3*R$i&22KY{Rh>{+ky7WIRz+Z{sAa*qdq6H~3 zmn!5+-GqULH+mhtp1PX;->`Bp8<2h(@L>F}xb}EF7Oa_P$G`3tB&=KrC=u*!23y>! zjF&JPb94tgC8jjR_ja_dNoL_vzmUdy4oFI?v#Np@-|s+pI-Z*@eU2;Lxows-?U7Mp z^phxw!2U_>H|v^AY_2j;%ks$nDT(aVx{^eHKcl7%X2m^<>IgjiBeKHEu!8JJq&iIx zJc~hFCL|Yn1}j_L4DERQ-XEt3cs1QDt~B?yQ$Tw*PHhd>77( zPJSW{SwyyN_gA$LovuZ6q>$W_HeJO&4&4;mchqG0r(Dh{td_Fyi-o}FqdL?Y5A^si zHktV0YW7jmzqrqCbYR9cN2@t(aa**DY&(2eQ5D{5v|v@_wt2#WKO4w~@qh|c?vkIu*TVH@pd1;Oi7(9j76zs1azkSz(`(wK|1wu%d_o`S&014ad0%J$bX}0fdh@s7 zM6iuRdmrBOW*I&ucs2S`uLTA}lBCoYm2&AT3-onS!¢7?7V@3<&Aw5zyEdN*S{ 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%0As<#Gln}f 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 diff --git a/doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.png b/doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.png deleted file mode 100644 index 9f8b8b2ce56f778fb98a2b7adc9473cb817db360..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60288 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%0DK^k`;OG?kBx#lxX4=_y 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 diff --git a/doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.svg b/doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.svg deleted file mode 100644 index e43e3b6123..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/figures/swift_install_arch.svg +++ /dev/null @@ -1,15245 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - David Pravec <alekibango@danix.org> - - - - - released under terms of Apache License - - - - - - - - - - - - - - - - - - - - - - - - - - OpenStack Object Storage Stores container databases, account databases, and stored objects - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Proxy node Public Switch - - - - - - - Storage nodes - - - - - - - - - - - - - - - - - - - - - - - Private Switch Auth node - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/src/docbkx/openstack-object-storage-admin/locale/openstack-object-storage-admin.pot b/doc/src/docbkx/openstack-object-storage-admin/locale/openstack-object-storage-admin.pot deleted file mode 100644 index f84781ff03..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/locale/openstack-object-storage-admin.pot +++ /dev/null @@ -1,3288 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2013-03-12 15:10+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:5(title) -msgid "Introduction to OpenStack Object Storage" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:6(para) -msgid "OpenStack Object Storage is a scalable object storage system - it is not a file system in the traditional sense. You will not be able to mount this system like traditional SAN or NAS volumes. Since OpenStack Object Storage is a different way of thinking when it comes to storage, take a few moments to review the key concepts listed below." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:11(title) -msgid "Accounts and Account Servers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:12(para) -msgid "The OpenStack Object Storage system is designed to be used by many different storage consumers or customers. Each user must identify themselves using an authentication system." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:15(para) -msgid "Nodes that run the Account service are a separate concept from individual accounts. Account servers are part of the storage system and must be configured along with Container servers and Object servers." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:20(title) -msgid "Authentication and Access Permissions" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:21(para) -msgid "You must authenticate against an Authentication service to receive OpenStack Object Storage connection parameters and an authentication token. The token must be passed in for all subsequent container/object operations. One authentication service that you can use as a middleware example is called swauth and you can download it from https://github.com/gholt/swauth. You can also integrate with the OpenStack Identity Service, code-named Keystone, which you can download from https://github.com/openstack/keystone." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:27(para) -msgid "Typically the language-specific APIs handle authentication, token passing, and HTTPS request/response communication." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:31(para) -msgid "You can implement access control for objects either for users or accounts using X-Container-Read: accountname and X-Container-Write: accountname:username, which allows any user from the accountname account to read but only allows the username user from the accountname account to write. You can also grant public access to objects stored in OpenStack Object Storage but also limit public access using the Referer header to prevent site-based content theft such as hot-linking (for example, linking to an image file from off-site and therefore using other's bandwidth). The public container settings are used as the default authorization over access control lists. For example, using X-Container-Read: referer:any allows anyone to read from the container regardless of other authorization settings." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:41(para) -msgid "Generally speaking, each user has their own storage account and has full access to that account. Users must authenticate with their credentials as described above, but once authenticated they can create/delete containers and objects within that account. The only way a user can access the content from another account is if they share an API access key or a session token provided by your authentication system." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:48(title) -msgid "Containers and Objects" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:49(para) -msgid "A container is a storage compartment for your data and provides a way for you to organize your data. You can think of a container as a folder in Windows® or a directory in UNIX®. The primary difference between a container and these other file system concepts is that containers cannot be nested. You can, however, create an unlimited number of containers within your account. Data must be stored in a container so you must have at least one container defined in your account prior to uploading data." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:55(para) -msgid "The only restrictions on container names is that they cannot contain a forward slash (/) and must be less than 256 bytes in length. Please note that the length restriction applies to the name after it has been URL encoded. For example, a container name of Course Docs would be URL encoded as Course%20Docs and therefore be 13 bytes in length rather than the expected 11." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:61(para) -msgid "An object is the basic storage entity and any optional metadata that represents the files you store in the OpenStack Object Storage system. When you upload data to OpenStack Object Storage, the data is stored as-is (no compression or encryption) and consists of a location (container), the object's name, and any metadata consisting of key/value pairs. For instance, you may chose to store a backup of your digital photos and organize them into albums. In this case, each object could be tagged with metadata such as Album : Caribbean Cruise or Album : Aspen Ski Trip." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:68(para) -msgid "The only restriction on object names is that they must be less than 1024 bytes in length after URL encoding. For example, an object name of C++final(v2).txt should be URL encoded as C%2B%2Bfinal%28v2%29.txt and therefore be 24 bytes in length rather than the expected 16." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:72(para) -msgid "The maximum allowable size for a storage object upon upload is 5 gigabytes (GB) and the minimum is zero bytes. You can use the built-in large object support and the swift utility to retrieve objects larger than 5 GB." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:75(para) -msgid "For metadata, you should not exceed 90 individual key/value pairs for any one object and the total byte length of all key/value pairs should not exceed 4KB (4096 bytes)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:77(title) -msgid "Warning" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:77(para) -msgid "The Object Storage API uses HTTP which specifies that header fields, such as those used to send metadata are case insensitive. Please do not expect the case of metadata items being preserved." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:82(title) -msgid "Operations" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:83(para) -msgid "Operations are the actions you perform within an OpenStack Object Storage system such as creating or deleting containers, uploading or downloading objects, and so on. The full list of operations is documented in the Developer Guide. Operations may be performed via the REST web service API or a language-specific API; currently, we support Python, PHP, Java, Ruby, and C#/.NET." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:89(para) -msgid "All operations must include a valid authorization token from your authorization system." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:94(title) -msgid "Language-Specific API Bindings" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:95(para) -msgid "A set of supported API bindings in several popular languages are available from the Rackspace Cloud Files product, which uses OpenStack Object Storage code for its implementation. These bindings provide a layer of abstraction on top of the base REST API, allowing programmers to work with a container and object model instead of working directly with HTTP requests and responses. These bindings are free (as in beer and as in speech) to download, use, and modify. They are all licensed under the MIT License as described in the COPYING file packaged with each binding. If you do make any improvements to an API, you are encouraged (but not required) to submit those changes back to us." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:104(para) -msgid "The API bindings for Rackspace Cloud Files are hosted at http://github.com/rackspace. Feel free to coordinate your changes through github or, if you prefer, send your changes to cloudfiles@rackspacecloud.com. Just make sure to indicate which language and version you modified and send a unified diff." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:109(para) -msgid "Each binding includes its own documentation (either HTML, PDF, or CHM). They also include code snippets and examples to help you get started. The currently supported API binding for OpenStack Object Storage are:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:114(para) -msgid "PHP (requires 5.x and the modules: cURL, FileInfo, mbstring)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:117(para) -msgid "Python (requires 2.4 or newer)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:120(para) -msgid "Java (requires JRE v1.5 or newer)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:123(para) -msgid "C#/.NET (requires .NET Framework v3.5)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:126(para) -msgid "Ruby (requires 1.8 or newer and mime-tools module)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/aboutobjectstorage.xml:129(para) -msgid "There are no other supported language-specific bindings at this time. You are welcome to create your own language API bindings and we can help answer any questions during development, host your code if you like, and give you full credit for your work." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:6(title) -msgid "System Administration for OpenStack Object Storage" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:7(para) -msgid "By understanding the concepts inherent to the Object Storage system you can better monitor and administer your storage solution." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:11(title) -msgid "Understanding How Object Storage Works" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:12(para) -msgid "This section offers a brief overview of each concept in administering Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:13(title) -msgid "The Ring" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:15(para) -msgid "A ring represents a mapping between the names of entities stored on disk and their physical location. There are separate rings for accounts, containers, and objects. When other components need to perform any operation on an object, container, or account, they need to interact with the appropriate ring to determine its location in the cluster." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:17(para) -msgid "The Ring maintains this mapping using zones, devices, partitions, and replicas. Each partition in the ring is replicated, by default, 3 times across the cluster, and the locations for a partition are stored in the mapping maintained by the ring. The ring is also responsible for determining which devices are used for handoff in failure scenarios." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:19(para) -msgid "Data can be isolated with the concept of zones in the ring. Each replica of a partition is guaranteed to reside in a different zone. A zone could represent a drive, a server, a cabinet, a switch, or even a datacenter." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:21(para) -msgid "The partitions of the ring are equally divided among all the devices in the OpenStack Object Storage installation. When partitions need to be moved around (for example if a device is added to the cluster), the ring ensures that a minimum number of partitions are moved at a time, and only one replica of a partition is moved at a time." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:23(para) -msgid "Weights can be used to balance the distribution of partitions on drives across the cluster. This can be useful, for example, when different sized drives are used in a cluster." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:25(para) -msgid "The ring is used by the Proxy server and several background processes (like replication)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:26(title) -msgid "Proxy Server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:27(para) -msgid "The Proxy Server is responsible for tying together the rest of the OpenStack Object Storage architecture. For each request, it will look up the location of the account, container, or object in the ring (see below) and route the request accordingly. The public API is also exposed through the Proxy Server." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:29(para) -msgid "A large number of failures are also handled in the Proxy Server. For example, if a server is unavailable for an object PUT, it will ask the ring for a hand-off server and route there instead." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:32(para) -msgid "When objects are streamed to or from an object server, they are streamed directly through the proxy server to or from the user – the proxy server does not spool them." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:33(para) -msgid "You can use a proxy server with account management enabled by configuring it in the proxy server configuration file." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:36(title) -msgid "Object Server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:38(para) -msgid "The Object Server is a very simple blob storage server that can store, retrieve and delete objects stored on local devices. Objects are stored as binary files on the filesystem with metadata stored in the file’s extended attributes (xattrs). This requires that the underlying filesystem choice for object servers support xattrs on files. Some filesystems, like ext3, have xattrs turned off by default." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:40(para) -msgid "Each object is stored using a path derived from the object name’s hash and the operation’s timestamp. Last write always wins, and ensures that the latest object version will be served. A deletion is also treated as a version of the file (a 0 byte file ending with “.ts”, which stands for tombstone). This ensures that deleted files are replicated correctly and older versions don’t magically reappear due to failure scenarios." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:43(title) -msgid "Container Server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:45(para) -msgid "The Container Server’s primary job is to handle listings of objects. It doesn’t know where those objects are, just what objects are in a specific container. The listings are stored as sqlite database files, and replicated across the cluster similar to how objects are. Statistics are also tracked that include the total number of objects, and total storage usage for that container." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:47(title) -msgid "Account Server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:48(para) -msgid "The Account Server is very similar to the Container Server, excepting that it is responsible for listings of containers rather than objects." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:51(title) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:649(title) -msgid "Replication" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:53(para) -msgid "Replication is designed to keep the system in a consistent state in the face of temporary error conditions like network outages or drive failures." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:55(para) -msgid "The replication processes compare local data with each remote copy to ensure they all contain the latest version. Object replication uses a hash list to quickly compare subsections of each partition, and container and account replication use a combination of hashes and shared high water marks." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:57(para) -msgid "Replication updates are push based. For object replication, updating is just a matter of rsyncing files to the peer. Account and container replication push missing records over HTTP or rsync whole database files." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:59(para) -msgid "The replicator also ensures that data is removed from the system. When an item (object, container, or account) is deleted, a tombstone is set as the latest version of the item. The replicator will see the tombstone and ensure that the item is removed from the entire system." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:61(title) -msgid "Updaters" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:63(para) -msgid "There are times when container or account data can not be immediately updated. This usually occurs during failure scenarios or periods of high load. If an update fails, the update is queued locally on the file system, and the updater will process the failed updates. This is where an eventual consistency window will most likely come in to play. For example, suppose a container server is under load and a new object is put in to the system. The object will be immediately available for reads as soon as the proxy server responds to the client with success. However, the container server did not update the object listing, and so the update would be queued for a later update. Container listings, therefore, may not immediately contain the object." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:73(para) -msgid "In practice, the consistency window is only as large as the frequency at which the updater runs and may not even be noticed as the proxy server will route listing requests to the first container server which responds. The server under load may not be the one that serves subsequent listing requests – one of the other two replicas may handle the listing." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:75(title) -msgid "Auditors" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:77(para) -msgid "Auditors crawl the local server checking the integrity of the objects, containers, and accounts. If corruption is found (in the case of bit rot, for example), the file is quarantined, and replication will replace the bad file from another replica. If other errors are found they are logged (for example, an object’s listing can’t be found on any container server it should be)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:85(title) -msgid "Object Layout on Storage" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:86(para) -msgid "Swift uses the underlying filesystem to store the data on disk. An administrator can use normal filesystem tools to find and inspect this data. Swift uses the following convention for storing objects:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:90(replaceable) -msgid "path_to_mount_points" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:90(replaceable) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:444(td) -msgid "device" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:90(replaceable) -msgid "partition" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:90(replaceable) -msgid "hash_suffix" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:90(replaceable) -msgid "hash/" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:89(filename) -msgid "///objects///" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:91(para) -msgid "Accounts and containers are stored similarly, with the \"objects\" part of the path replaced with \"accounts\" or \"containers\"." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:93(para) -msgid "The directory is where all of the data for the object is stored. Inside the directory, there is normally just one file (named <timestamp>.data). The object's data is stored in the file, and the object's metadata is stored in the extended attributes (xattrs) of the file." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:98(para) -msgid "If a user deletes the object, the .data file is deleted and a <timestamp>.ts (\"ts\" for \"tombstone\") file is created as a zero-byte file. This is a delete marker that will be eventually reaped, but it exists to ensure that the delete properly propagates to all replicas in the cluster." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:103(para) -msgid "Swift uses this scheme of timestamps in the file name to implement conflict resolution. Each piece of data is assigned a timestamp by the proxy server when the request comes to the cluster, and that timestamp is what's used to name the file on disk on the object (or account or container) server. For the common case, there will be a single file in the directory. If Swift receives multiple, concurrent requests to write to the same object, it can happen that multiple .data files are written to this directory. Swift uses \"last-write-wins\" to resolve such conflicts, choosing the most recent file by timestamp." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:115(title) -msgid "Configuring and Tuning OpenStack Object Storage" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:116(para) -msgid "This section walks through deployment options and considerations." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:118(para) -msgid "You have multiple deployment options to choose from. The swift services run completely autonomously, which provides for a lot of flexibility when designing the hardware deployment for swift. The 4 main services are:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:122(para) -msgid "Proxy Services" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:123(para) -msgid "Object Services" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:124(para) -msgid "Container Services" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:125(para) -msgid "Account Services" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:128(para) -msgid "The Proxy Services are more CPU and network I/O intensive. If you are using 10g networking to the proxy, or are terminating SSL traffic at the proxy, greater CPU power will be required." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:131(para) -msgid "The Object, Container, and Account Services (Storage Services) are more disk and network I/O intensive." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:133(para) -msgid "The easiest deployment is to install all services on each server. There is nothing wrong with doing this, as it scales each service out horizontally." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:135(para) -msgid "At Rackspace, we put the Proxy Services on their own servers and all of the Storage Services on the same server. This allows us to send 10g networking to the proxy and 1g to the storage servers, and keep load balancing to the proxies more manageable. Storage Services scale out horizontally as storage servers are added, and we can scale overall API throughput by adding more Proxies." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:141(para) -msgid "If you need more throughput to either Account or Container Services, they may each be deployed to their own servers. For example you might use faster (but more expensive) SAS or even SSD drives to get faster disk I/O to the databases." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:144(para) -msgid "Load balancing and network design is left as an exercise to the reader, but this is a very important part of the cluster, so time should be spent designing the network for a Swift cluster." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:150(title) -msgid "Preparing the Ring" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:151(title) -msgid "Note" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:151(para) -msgid "\"Partition\" in this section refers to the logical partitions of the swift ring - not physical partitions on Storage node drives. You should setup your Storage Node disk partitions with one physical partition per disk, as per the installation instructions ." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:157(para) -msgid "The first step is to determine the number of partitions that will be in the ring. We recommend that there be a minimum of 100 partitions per drive to insure even distribution across the drives. A good starting point might be to figure out the maximum number of drives the cluster will contain, and then multiply by 100, and then round up to the nearest power of two." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:162(para) -msgid "For example, imagine we are building a cluster that will have no more than 5,000 drives. That would mean that we would have a total number of 500,000 partitions, which is pretty close to 2^19, rounded up." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:165(para) -msgid "It is also a good idea to keep the number of partitions small (relatively). The more partitions there are, the more work that has to be done by the replicators and other backend jobs and the more memory the rings consume in process. The goal is to find a good balance between small rings and maximum cluster size." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:170(para) -msgid "The next step is to determine the number of replicas to store of the data. Currently it is recommended to use 3 (as this is the only value that has been tested). The higher the number, the more storage that is used but the less likely you are to lose data." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:175(para) -msgid "It is also important to determine how many zones the cluster should have. It is recommended to start with a minimum of 5 zones. You can start with fewer, but our testing has shown that having at least five zones is optimal when failures occur. We also recommend trying to configure the zones at as high a level as possible to create as much isolation as possible. Some example things to take into consideration can include physical location, power availability, and network connectivity. For example, in a small cluster you might decide to split the zones up by cabinet, with each cabinet having its own power and network connectivity. The zone concept is very abstract, so feel free to use it in whatever way best isolates your data from failure. Zones are referenced by number, beginning with 1." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:186(para) -msgid "You can now start building the ring with:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:189(para) -msgid "This will start the ring build process creating the <builder_file> with 2^<part_power> partitions. <min_part_hours> is the time in hours before a specific partition can be moved in succession (24 is a good value for this)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:193(para) -msgid "Devices can be added to the ring with:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:197(para) -msgid "This will add a device to the ring where <builder_file> is the name of the builder file that was created previously, <zone> is the number of the zone this device is in, <ip> is the ip address of the server the device is in, <port> is the port number that the server is running on, <device_name> is the name of the device on the server (for example: sdb1), <meta> is a string of metadata for the device (optional), and <weight> is a float weight that determines how many partitions are put on the device relative to the rest of the devices in the cluster (a good starting point is 100.0 x TB on the drive). Add each device that will be initially in the cluster." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:207(para) -msgid "Once all of the devices are added to the ring, run:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:210(para) -msgid "This will distribute the partitions across the drives in the ring. It is important whenever making changes to the ring to make all the changes required before running rebalance. This will ensure that the ring stays as balanced as possible, and as few partitions are moved as possible." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:214(para) -msgid "The above process should be done to make a ring for each storage service (Account, Container and Object). The builder files will be needed in future changes to the ring, so it is very important that these be kept and backed up. The resulting .tar.gz ring file should be pushed to all of the servers in the cluster. For more information about building rings, running swift-ring-builder with no options will display help text with available commands and options." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:224(title) -msgid "Considerations and Tuning" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:224(para) -msgid "Fine-tuning your deployment and installation may take some time and effort. Here are some considerations for improving performance of an OpenStack Object Storage installation." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:226(title) -msgid "Memcached Considerations" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:228(para) -msgid "Several of the Services rely on Memcached for caching certain types of lookups, such as auth tokens, and container/account existence. Swift does not do any caching of actual object data. Memcached should be able to run on any servers that have available RAM and CPU. At Rackspace, we run Memcached on the proxy servers. The memcache_servers config option in the proxy-server.conf should contain all memcached servers." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:236(title) -msgid "System Time" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:237(para) -msgid "Time may be relative but it is relatively important for Swift! Swift uses timestamps to determine which is the most recent version of an object. It is very important for the system time on each server in the cluster to by synced as closely as possible (more so for the proxy server, but in general it is a good idea for all the servers). At Rackspace, we use NTP with a local NTP server to ensure that the system times are as close as possible. This should also be monitored to ensure that the times do not vary too much." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:247(title) -msgid "General Service Tuning" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:248(para) -msgid "Most services support either a worker or concurrency value in the settings. This allows the services to make effective use of the cores available. A good starting point to set the concurrency level for the proxy and storage services to 2 times the number of cores available. If more than one service is sharing a server, then some experimentation may be needed to find the best balance." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:254(para) -msgid "At Rackspace, our Proxy servers have dual quad core processors, giving us 8 cores. Our testing has shown 16 workers to be a pretty good balance when saturating a 10g network and gives good CPU utilization." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:257(para) -msgid "Our Storage servers all run together on the same servers. These servers have dual quad core processors, for 8 cores total. We run the Account, Container, and Object servers with 8 workers each. Most of the background jobs are run at a concurrency of 1, with the exception of the replicators which are run at a concurrency of 2." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:262(para) -msgid "The above configuration setting should be taken as suggestions and testing of configuration settings should be done to ensure best utilization of CPU, network connectivity, and disk I/O." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:267(title) -msgid "RAID Considerations" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:268(para) -msgid "We recommend that you do not use RAID with Swift." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:269(para) -msgid "The workload for Swift is very write-heavy, with small random IO accesses. This type of workload performs very poorly for most parity RAID (e.g., RAID 2-6). Testing done by Rackspace suggests that under heavy workloads, the overall RAID performance can degrade to be as slow as a single drive." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:273(para) -msgid "Furthermore, a drive failure in a RAID array can result in very poor performance on the node until the RAID rebuilds, which can take a long time. Testing at Rackspace, using nodes with 24 2T drives, revealed that a RAID rebuild after a drive failure could take on the order of two weeks, during which time the node performance suffered dramatically as the RAID array functioned in a degraded state. This kind of significantly degraded performance can potentially have ripple effects across the rest of the cluster." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:282(title) -msgid "Filesystem Considerations" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:283(para) -msgid "Swift is designed to be mostly filesystem agnostic–the only requirement being that the filesystem supports extended attributes (xattrs). After thorough testing with our use cases and hardware configurations, XFS was the best all-around choice. If you decide to use a filesystem other than XFS, we highly recommend thorough testing." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:289(para) -msgid "If you are using XFS, some settings that can dramatically impact performance. We recommend the following when creating the XFS partition:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:292(code) -msgid "mkfs.xfs -i size=1024 -f /dev/sda1" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:294(para) -msgid "Setting the inode size is important, as XFS stores xattr data in the inode. If the metadata is too large to fit in the inode, a new extent is created, which can cause quite a performance problem. Upping the inode size to 1024 bytes provides enough room to write the default metadata, plus a little headroom. We do not recommend running Swift on RAID, but if you are using RAID it is also important to make sure that the proper sunit and swidth settings get set so that XFS can make most efficient use of the RAID array." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:301(para) -msgid "We also recommend the following example mount options when using XFS:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:302(code) -msgid "mount -t xfs -o noatime,nodiratime,nobarrier,logbufs=8 /dev/sda1 /srv/node/sda" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:304(para) -msgid "For a standard swift install, all data drives are mounted directly under /srv/node (as can be seen in the above example of mounting /dev/sda1 as /srv/node/sda). If you choose to mount the drives in another directory, be sure to set the devices config option in all of the server configs to point to the correct directory." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:312(title) -msgid "General System Tuning" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:313(para) -msgid "Rackspace currently runs Swift on Ubuntu Server 10.04, and the following changes have been found to be useful for our use cases." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:315(para) -msgid "The following settings should be in /etc/sysctl.conf:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:330(para) -msgid "To load the updated sysctl settings, run sudo sysctl -p " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:331(para) -msgid "A note about changing the TIME_WAIT values. By default the OS will hold a port open for 60 seconds to ensure that any remaining packets can be received. During high usage, and with the number of connections that are created, it is easy to run out of ports. We can change this since we are in control of the network. If you are not in control of the network, or do not expect high loads, then you may not want to adjust those values." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:337(para) -msgid "Another helpful tuning parameter on slower systems that helps to ensure enough time is allowed for service restarts is the -k N (or --kill-wait N ) parameter of . This allows you to change the default (15 second) time (N, in seconds) that swift waits for processes to die and notably you can pass flag with to set where PID's will be stored." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:347(title) -msgid "Logging Considerations" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:348(para) -msgid "Swift is set up to log directly to syslog. Every service can be configured with the log_facility option to set the syslog log facility destination. We recommend using syslog-ng to route the logs to specific log files locally on the server and also to remote log collecting servers." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:355(title) -msgid "Working with Rings" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:356(para) -msgid "The rings determine where data should reside in the cluster. There is a separate ring for account databases, container databases, and individual objects but each ring works in the same way. These rings are externally managed, in that the server processes themselves do not modify the rings, they are instead given new rings modified by other tools." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:361(para) -msgid "The ring uses a configurable number of bits from a path's MD5 hash as a partition index that designates a device. The number of bits kept from the hash is known as the partition power, and 2 to the partition power indicates the partition count. Partitioning the full MD5 hash ring allows other parts of the cluster to work in batches of items at once which ends up either more efficient or at least less complex than working with each item separately or the entire cluster all at once." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:368(para) -msgid "Another configurable value is the replica count, which indicates how many of the partition->device assignments comprise a single ring. For a given partition number, each replica's device will not be in the same zone as any other replica's device. Zones can be used to group devices based on physical locations, power separations, network separations, or any other attribute that would lessen multiple replicas being unavailable at the same time." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:375(title) -msgid "Managing Rings with the Ring Builder" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:376(para) -msgid "The rings are built and managed manually by a utility called the ring-builder. The ring-builder assigns partitions to devices and writes an optimized Python structure to a gzipped, pickled file on disk for shipping out to the servers. The server processes just check the modification time of the file occasionally and reload their in-memory copies of the ring structure as needed. Because of how the ring-builder manages changes to the ring, using a slightly older ring usually just means one of the three replicas for a subset of the partitions will be incorrect, which can be easily worked around." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:384(para) -msgid "The ring-builder also keeps its own builder file with the ring information and additional data required to build future rings. It is very important to keep multiple backup copies of these builder files. One option is to copy the builder files out to every server while copying the ring files themselves. Another is to upload the builder files into the cluster itself. Complete loss of a builder file will mean creating a new ring from scratch, nearly all partitions will end up assigned to different devices, and therefore nearly all data stored will have to be replicated to new locations. So, recovery from a builder file loss is possible, but data will definitely be unreachable for an extended time." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:395(title) -msgid "About the Ring Data Structure" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:396(para) -msgid "The ring data structure consists of three top level fields: a list of devices in the cluster, a list of lists of device ids indicating partition to device assignments, and an integer indicating the number of bits to shift an MD5 hash to calculate the partition for the hash." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:401(title) -msgid "List of Devices in the Ring" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:403(para) -msgid "The list of devices is known internally to the Ring class as devs. Each item in the list of devices is a dictionary with the following keys:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:406(caption) -msgid "List of Devices and Keys" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:409(td) -msgid "Key" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:410(td) -msgid "Type" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:411(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:846(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:953(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:988(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1044(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1144(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1182(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1212(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1372(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:25(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:141(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:234(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:341(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:392(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:449(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:505(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:615(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:669(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:739(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:795(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:832(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:873(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:961(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1002(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1085(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1122(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1179(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1234(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1327(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1398(td) -msgid "Description" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:413(td) -msgid "id" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:414(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:419(td) -msgid "integer" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:415(td) -msgid "The index into the list devices." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:417(td) -msgid "zone" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:420(td) -msgid "The zone the devices resides in." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:422(td) -msgid "weight" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:423(td) -msgid "float" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:424(td) -msgid "The relative weight of the device in comparison to other devices. This usually corresponds directly to the amount of disk space the device has compared to other devices. For instance a device with 1 terabyte of space might have a weight of 100.0 and another device with 2 terabytes of space might have a weight of 200.0. This weight can also be used to bring back into balance a device that has ended up with more or less data than desired over time. A good average weight of 100.0 allows flexibility in lowering the weight later if necessary." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:434(td) -msgid "ip" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:435(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:445(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:451(td) -msgid "string" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:436(td) -msgid "The IP address of the server containing the device." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:439(td) -msgid "port" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:440(td) -msgid "int" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:441(td) -msgid "The TCP port the listening server process uses that serves requests for the device." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:446(td) -msgid "The on disk name of the device on the server. For example: sdb1" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:449(td) -msgid "meta" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:452(td) -msgid "A general-use field for storing additional information for the device. This information isn't used directly by the server processes, but can be useful in debugging. For example, the date and time of installation and hardware manufacturer could be stored here." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:460(para) -msgid "Note: The list of devices may contain holes, or indexes set to None, for devices that have been removed from the cluster. Generally, device ids are not reused. Also, some devices may be temporarily disabled by setting their weight to 0.0." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:468(title) -msgid "Partition Assignment List" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:469(para) -msgid "This is a list of array(‘I') of devices ids. The outermost list contains an array(‘I') for each replica. Each array(‘I') has a length equal to the partition count for the ring. Each integer in the array(‘I') is an index into the above list of devices. The partition list is known internally to the Ring class as _replica2part2dev_id." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:475(para) -msgid "So, to create a list of device dictionaries assigned to a partition, the Python code would look like: devices = [self.devs[part2dev_id[partition]] for part2dev_id in self._replica2part2dev_id]" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:477(para) -msgid "array(‘I') is used for memory conservation as there may be millions of partitions." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:482(title) -msgid "Partition Shift Value" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:483(para) -msgid "The partition shift value is known internally to the Ring class as _part_shift. This value used to shift an MD5 hash to calculate the partition on which the data for that hash should reside. Only the top four bytes of the hash is used in this process. For example, to compute the partition for the path /account/container/object the Python code might look like: partition = unpack_from('>I', md5('/account/container/object').digest())[0] >>self._part_shift" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:491(title) -msgid "Building the Ring" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:492(para) -msgid "The initial building of the ring first calculates the number of partitions that should ideally be assigned to each device based the device's weight. For example, if the partition power of 20 the ring will have 1,048,576 partitions. If there are 1,000 devices of equal weight they will each desire 1,048.576 partitions. The devices are then sorted by the number of partitions they desire and kept in order throughout the initialization process." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:498(para) -msgid "Then, the ring builder assigns each partition's replica to the device that desires the most partitions at that point, with the restriction that the device is not in the same zone as any other replica for that partition. Once assigned, the device's desired partition count is decremented and moved to its new sorted location in the list of devices and the process continues." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:503(para) -msgid "When building a new ring based on an old ring, the desired number of partitions each device wants is recalculated. Next the partitions to be reassigned are gathered up. Any removed devices have all their assigned partitions unassigned and added to the gathered list. Any devices that have more partitions than they now desire have random partitions unassigned from them and added to the gathered list. Lastly, the gathered partitions are then reassigned to devices using a similar method as in the initial assignment described above." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:510(para) -msgid "Whenever a partition has a replica reassigned, the time of the reassignment is recorded. This is taken into account when gathering partitions to reassign so that no partition is moved twice in a configurable amount of time. This configurable amount of time is known internally to the RingBuilder class as min_part_hours. This restriction is ignored for replicas of partitions on devices that have been removed, as removing a device only happens on device failure and there's no choice but to make a reassignment." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:518(para) -msgid "The above processes don't always perfectly rebalance a ring due to the random nature of gathering partitions for reassignment. To help reach a more balanced ring, the rebalance process is repeated until near perfect (less 1% off) or when the balance doesn't improve by at least 1% (indicating we probably can't get perfect balance due to wildly imbalanced zones or too many partitions recently moved)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:526(title) -msgid "History of the Ring Design" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:527(para) -msgid "The ring code went through many iterations before arriving at what it is now and while it has been stable for a while now, the algorithm may be tweaked or perhaps even fundamentally changed if new ideas emerge. This section will try to describe the previous ideas attempted and attempt to explain why they were discarded." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:532(para) -msgid "A “live ring” option was considered where each server could maintain its own copy of the ring and the servers would use a gossip protocol to communicate the changes they made. This was discarded as too complex and error prone to code correctly in the project time span available. One bug could easily gossip bad data out to the entire cluster and be difficult to recover from. Having an externally managed ring simplifies the process, allows full validation of data before it's shipped out to the servers, and guarantees each server is using a ring from the same timeline. It also means that the servers themselves aren't spending a lot of resources maintaining rings." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:542(para) -msgid "A couple of “ring server” options were considered. One was where all ring lookups would be done by calling a service on a separate server or set of servers, but this was discarded due to the latency involved. Another was much like the current process but where servers could submit change requests to the ring server to have a new ring built and shipped back out to the servers. This was discarded due to project time constraints and because ring changes are currently infrequent enough that manual control was sufficient. However, lack of quick automatic ring changes did mean that other parts of the system had to be coded to handle devices being unavailable for a period of hours until someone could manually update the ring." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:552(para) -msgid "The current ring process has each replica of a partition independently assigned to a device. A version of the ring that used a third of the memory was tried, where the first replica of a partition was directly assigned and the other two were determined by “walking” the ring until finding additional devices in other zones. This was discarded as control was lost as to how many replicas for a given partition moved at once. Keeping each replica independent allows for moving only one partition replica within a given time window (except due to device failures). Using the additional memory was deemed a good tradeoff for moving data around the cluster much less often." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:561(para) -msgid "Another ring design was tried where the partition to device assignments weren't stored in a big list in memory but instead each device was assigned a set of hashes, or anchors. The partition would be determined from the data item's hash and the nearest device anchors would determine where the replicas should be stored. However, to get reasonable distribution of data each device had to have a lot of anchors and walking through those anchors to find replicas started to add up. In the end, the memory savings wasn't that great and more processing power was used, so the idea was discarded." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:569(para) -msgid "A completely non-partitioned ring was also tried but discarded as the partitioning helps many other parts of the system, especially replication. Replication can be attempted and retried in a partition batch with the other replicas rather than each data item independently attempted and retried. Hashes of directory structures can be calculated and compared with other replicas to reduce directory walking and network traffic." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:576(para) -msgid "Partitioning and independently assigning partition replicas also allowed for the best balanced cluster. The best of the other strategies tended to give +-10% variance on device balance with devices of equal weight and +-15% with devices of varying weights. The current strategy allows us to get +-3% and +-8% respectively." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:581(para) -msgid "Various hashing algorithms were tried. SHA offers better security, but the ring doesn't need to be cryptographically secure and SHA is slower. Murmur was much faster, but MD5 was built-in and hash computation is a small percentage of the overall request handling time. In all, once it was decided the servers wouldn't be maintaining the rings themselves anyway and only doing hash lookups, MD5 was chosen for its general availability, good distribution, and adequate speed." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:590(title) -msgid "The Account Reaper" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:591(para) -msgid "The Account Reaper removes data from deleted accounts in the background." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:592(para) -msgid "An account is marked for deletion by a reseller through the services server's remove_storage_account XMLRPC call. This simply puts the value DELETED into the status column of the account_stat table in the account database (and replicas), indicating the data for the account should be deleted later. There is no set retention time and no undelete; it is assumed the reseller will implement such features and only call remove_storage_account once it is truly desired the account's data be removed." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:600(para) -msgid "The account reaper runs on each account server and scans the server occasionally for account databases marked for deletion. It will only trigger on accounts that server is the primary node for, so that multiple account servers aren't all trying to do the same work at the same time. Using multiple servers to delete one account might improve deletion speed, but requires coordination so they aren't duplicating effort. Speed really isn't as much of a concern with data deletion and large accounts aren't deleted that often." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:607(para) -msgid "The deletion process for an account itself is pretty straightforward. For each container in the account, each object is deleted and then the container is deleted. Any deletion requests that fail won't stop the overall process, but will cause the overall process to fail eventually (for example, if an object delete times out, the container won't be able to be deleted later and therefore the account won't be deleted either). The overall process continues even on a failure so that it doesn't get hung up reclaiming cluster space because of one troublesome spot. The account reaper will keep trying to delete an account until it eventually becomes empty, at which point the database reclaim process within the db_replicator will eventually remove the database files." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:618(title) -msgid "Account Reaper Background and History" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:619(para) -msgid "At first, a simple approach of deleting an account through completely external calls was considered as it required no changes to the system. All data would simply be deleted in the same way the actual user would, through the public REST API. However, the downside was that it would use proxy resources and log everything when it didn't really need to. Also, it would likely need a dedicated server or two, just for issuing the delete requests." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:626(para) -msgid "A completely bottom-up approach was also considered, where the object and container servers would occasionally scan the data they held and check if the account was deleted, removing the data if so. The upside was the speed of reclamation with no impact on the proxies or logging, but the downside was that nearly 100% of the scanning would result in no action creating a lot of I/O load for no reason." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:632(para) -msgid "A more container server centric approach was also considered, where the account server would mark all the containers for deletion and the container servers would delete the objects in each container and then themselves. This has the benefit of still speedy reclamation for accounts with a lot of containers, but has the downside of a pretty big load spike. The process could be slowed down to alleviate the load spike possibility, but then the benefit of speedy reclamation is lost and what's left is just a more complex process. Also, scanning all the containers for those marked for deletion when the majority wouldn't be seemed wasteful. The db_replicator could do this work while performing its replication scan, but it would have to spawn and track deletion processes which seemed needlessly complex." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:643(para) -msgid "In the end, an account server centric approach seemed best, as described above." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:650(para) -msgid "Since each replica in OpenStack Object Storage functions independently, and clients generally require only a simple majority of nodes responding to consider an operation successful, transient failures like network partitions can quickly cause replicas to diverge. These differences are eventually reconciled by asynchronous, peer-to-peer replicator processes. The replicator processes traverse their local filesystems, concurrently performing operations in a manner that balances load across physical disks." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:651(para) -msgid "Replication uses a push model, with records and files generally only being copied from local to remote replicas. This is important because data on the node may not belong there (as in the case of handoffs and ring changes), and a replicator can't know what data exists elsewhere in the cluster that it should pull in. It's the duty of any node that contains data to ensure that data gets to where it belongs. Replica placement is handled by the ring." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:653(para) -msgid "Every deleted record or file in the system is marked by a tombstone, so that deletions can be replicated alongside creations. These tombstones are cleaned up by the replication process after a period of time referred to as the consistency window, which is related to replication duration and how long transient failures can remove a node from the cluster. Tombstone cleanup must be tied to replication to reach replica convergence." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:654(para) -msgid "If a replicator detects that a remote drive has failed, it will use the ring's “get_more_nodes” interface to choose an alternate node to synchronize with. The replicator can generally maintain desired levels of replication in the face of hardware failures, though some replicas may not be in an immediately usable location." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:655(para) -msgid "Replication is an area of active development, and likely rife with potential improvements to speed and correctness." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:656(para) -msgid "There are two major classes of replicator - the db replicator, which replicates accounts and containers, and the object replicator, which replicates object data." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:658(title) -msgid "Database Replication" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:659(para) -msgid "The first step performed by db replication is a low-cost hash comparison to find out whether or not two replicas already match. Under normal operation, this check is able to verify that most databases in the system are already synchronized very quickly. If the hashes differ, the replicator brings the databases in sync by sharing records added since the last sync point." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:661(para) -msgid "This sync point is a high water mark noting the last record at which two databases were known to be in sync, and is stored in each database as a tuple of the remote database id and record id. Database ids are unique amongst all replicas of the database, and record ids are monotonically increasing integers. After all new records have been pushed to the remote database, the entire sync table of the local database is pushed, so the remote database knows it's now in sync with everyone the local database has previously synchronized with." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:662(para) -msgid "If a replica is found to be missing entirely, the whole local database file is transmitted to the peer using rsync(1) and vested with a new unique id." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:663(para) -msgid "In practice, DB replication can process hundreds of databases per concurrency setting per second (up to the number of available CPUs or disks) and is bound by the number of DB transactions that must be performed." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:666(title) -msgid "Object Replication" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:667(para) -msgid "The initial implementation of object replication simply performed an rsync to push data from a local partition to all remote servers it was expected to exist on. While this performed adequately at small scale, replication times skyrocketed once directory structures could no longer be held in RAM. We now use a modification of this scheme in which a hash of the contents for each suffix directory is saved to a per-partition hashes file. The hash for a suffix directory is invalidated when the contents of that suffix directory are modified." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:668(para) -msgid "The object replication process reads in these hash files, calculating any invalidated hashes. It then transmits the hashes to each remote server that should hold the partition, and only suffix directories with differing hashes on the remote server are rsynced. After pushing files to the remote server, the replication process notifies it to recalculate hashes for the rsynced suffix directories." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:669(para) -msgid "Performance of object replication is generally bound by the number of uncached directories it has to traverse, usually as a result of invalidated suffix directory hashes. Using write volume and partition counts from our running systems, it was designed so that around 2% of the hash space on a normal node will be invalidated per day, which has experimentally given us acceptable replication speeds." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:675(title) -msgid "Managing Large Objects (Greater than 5 GB)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:676(para) -msgid "OpenStack Object Storage has a limit on the size of a single uploaded object; by default this is 5GB. However, the download size of a single object is virtually unlimited with the concept of segmentation. Segments of the larger object are uploaded and a special manifest file is created that, when downloaded, sends all the segments concatenated as a single object. This also offers much greater upload speed with the possibility of parallel uploads of the segments." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:683(title) -msgid "Using swift to Manage Segmented Objects" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:685(para) -msgid "The quickest way to try out this feature is use the included swift OpenStack Object Storage client tool. You can use the -S option to specify the segment size to use when splitting a large file. For example:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:690(para) -msgid "This would split the large_file into 1G segments and begin uploading those segments in parallel. Once all the segments have been uploaded, swift will then create the manifest file so the segments can be downloaded as one." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:693(para) -msgid "So now, the following st command would download the entire large object:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:697(para) -msgid "The swift CLI uses a strict convention for its segmented object support. In the above example it will upload all the segments into a second container named test_container_segments. These segments will have names like large_file/1290206778.25/21474836480/00000000, large_file/1290206778.25/21474836480/00000001, etc." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:702(para) -msgid "The main benefit for using a separate container is that the main container listings will not be polluted with all the segment names. The reason for using the segment name format of <name>/<timestamp>/<size>/<segment> is so that an upload of a new file with the same name won't overwrite the contents of the first until the last moment when the manifest file is updated." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:708(para) -msgid "The swift CLI will manage these segment files for you, deleting old segments on deletes and overwrites, etc. You can override this behavior with the --leave-segments option if desired; this is useful if you want to have multiple versions of the same large object available." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:714(title) -msgid "Direct API Management of Large Objects" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:715(para) -msgid "You can also work with the segments and manifests directly with HTTP requests instead of having swift do that for you. You can just upload the segments like you would any other object and the manifest is just a zero-byte file with an extra X-Object-Manifest header." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:720(para) -msgid "All the object segments need to be in the same container, have a common object name prefix, and their names sort in the order they should be concatenated. They don't have to be in the same container as the manifest file will be, which is useful to keep container listings clean as explained above with st." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:724(para) -msgid "The manifest file is simply a zero-byte file with the extra X-Object-Manifest:<container>/<prefix> header, where <container> is the container the object segments are in and <prefix> is the common prefix for all the segments." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:729(para) -msgid "It is best to upload all the segments first and then create or update the manifest. In this way, the full object won't be available for downloading until the upload is complete. Also, you can upload a new set of segments to a second location and then update the manifest to point to this new location. During the upload of the new segments, the original manifest will still be available to download the first set of segments." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:735(para) -msgid "Here's an example using curl with tiny 1-byte segments:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:736(para) -msgid "# First, upload the segments # Next, create the manifest file curl -X PUT -H 'X-Auth-Token: <token>' \\ -H 'X-Object-Manifest: container/myobject/' \\ http://<storage_url>/container/myobject --data-binary '' # And now we can download the segments as a single object curl -H 'X-Auth-Token: <token>' \\ http://<storage_url>/container/myobject" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:750(title) -msgid "Additional Notes on Large Objects" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:752(para) -msgid "With a GET or HEAD of a manifest file, the X-Object-Manifest: <container>/<prefix> header will be returned with the concatenated object so you can tell where it's getting its segments from." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:756(para) -msgid "The response's Content-Length for a GET or HEAD on the manifest file will be the sum of all the segments in the <container>/<prefix> listing, dynamically. So, uploading additional segments after the manifest is created will cause the concatenated object to be that much larger; there's no need to recreate the manifest file." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:762(para) -msgid "The response's Content-Type for a GET or HEAD on the manifest will be the same as the Content-Type set during the PUT request that created the manifest. You can easily change the Content-Type by reissuing the PUT." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:767(para) -msgid "The response's ETag for a GET or HEAD on the manifest file will be the MD5 sum of the concatenated string of ETags for each of the segments in the <container>/<prefix> listing, dynamically. Usually in OpenStack Object Storage the ETag is the MD5 sum of the contents of the object, and that holds true for each segment independently. But, it's not feasible to generate such an ETag for the manifest itself, so this method was chosen to at least offer change detection." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:777(title) -msgid "Large Object Storage History and Background" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:778(para) -msgid "Large object support has gone through various iterations before settling on this implementation." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:780(para) -msgid "The primary factor driving the limitation of object size in OpenStack Object Storage is maintaining balance among the partitions of the ring. To maintain an even dispersion of disk usage throughout the cluster the obvious storage pattern was to simply split larger objects into smaller segments, which could then be glued together during a read." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:785(para) -msgid "Before the introduction of large object support some applications were already splitting their uploads into segments and re-assembling them on the client side after retrieving the individual pieces. This design allowed the client to support backup and archiving of large data sets, but was also frequently employed to improve performance or reduce errors due to network interruption. The major disadvantage of this method is that knowledge of the original partitioning scheme is required to properly reassemble the object, which is not practical for some use cases, such as CDN origination." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:793(para) -msgid "In order to eliminate any barrier to entry for clients wanting to store objects larger than 5GB, initially we also prototyped fully transparent support for large object uploads. A fully transparent implementation would support a larger max size by automatically splitting objects into segments during upload within the proxy without any changes to the client API. All segments were completely hidden from the client API." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:799(para) -msgid "This solution introduced a number of challenging failure conditions into the cluster, wouldn't provide the client with any option to do parallel uploads, and had no basis for a resume feature. The transparent implementation was deemed just too complex for the benefit." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:804(para) -msgid "The current “user manifest” design was chosen in order to provide a transparent download of large objects to the client and still provide the uploading client a clean API to support segmented uploads." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:807(para) -msgid "Alternative “explicit” user manifest options were discussed which would have required a pre-defined format for listing the segments to “finalize” the segmented upload. While this may offer some potential advantages, it was decided that pushing an added burden onto the client which could potentially limit adoption should be avoided in favor of a simpler “API” (essentially just the format of the ‘X-Object-Manifest' header)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:814(para) -msgid "During development it was noted that this “implicit” user manifest approach which is based on the path prefix can be potentially affected by the eventual consistency window of the container listings, which could theoretically cause a GET on the manifest object to return an invalid whole object for that short term. In reality you're unlikely to encounter this scenario unless you're running very high concurrency uploads against a small testing environment which isn't running the object-updaters or container-replicators." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:821(para) -msgid "Like all of OpenStack Object Storage, Large Object Support is living feature which will continue to improve and may change over time." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:828(title) -msgid "Throttling Resources by Setting Rate Limits" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:830(para) -msgid "Rate limiting in OpenStack Object Storage is implemented as a pluggable middleware that you configure on the proxy server. Rate limiting is performed on requests that result in database writes to the account and container sqlite dbs. It uses memcached and is dependent on the proxy servers having highly synchronized time. The rate limits are limited by the accuracy of the proxy server clocks." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:837(title) -msgid "Configuration for Rate Limiting" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:838(para) -msgid "All configuration is optional. If no account or container limits are provided there will be no rate limiting. Configuration available:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:841(caption) -msgid "Configuration options for rate limiting in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:844(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:951(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:986(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1042(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1142(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1180(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1210(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1370(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:23(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:139(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:232(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:339(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:390(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:447(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:503(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:613(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:667(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:737(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:793(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:830(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:871(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:959(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1000(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1083(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1120(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1177(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1232(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1325(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1396(td) -msgid "Option" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:845(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:952(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:987(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1043(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1143(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1181(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1211(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1371(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:24(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:140(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:233(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:340(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:391(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:448(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:504(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:614(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:668(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:738(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:794(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:831(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:872(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:960(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1001(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1084(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1121(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1178(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1233(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1326(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1397(td) -msgid "Default" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:849(td) -msgid "clock_accuracy" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:850(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:926(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:688(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1021(td) -msgid "1000" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:851(td) -msgid "Represents how accurate the proxy servers' system clocks are with each other. 1000 means that all the proxies' clock are accurate to each other within 1 millisecond. No ratelimit should be higher than the clock accuracy." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:858(td) -msgid "max_sleep_time_seconds" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:859(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:276(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:783(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:851(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1068(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1264(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1269(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1294(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1304(td) -msgid "60" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:860(td) -msgid "App will immediately return a 498 response if the necessary sleep time ever exceeds the given max_sleep_time_seconds." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:865(td) -msgid "log_sleep_time_seconds" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:866(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:872(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:117(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:203(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:565(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:938(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1126(td) -msgid "0" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:867(td) -msgid "To allow visibility into rate limiting set this value > 0 and all sleeps greater than the number will be logged." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:871(td) -msgid "account_ratelimit" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:873(td) -msgid "If set, will limit all requests to /account_name and PUTs to /account_name/container_name. Number is in requests per second" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:879(td) -msgid "account_whitelist" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:880(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:885(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:890(td) -msgid "‘'" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:881(td) -msgid "Comma separated lists of account names that will not be rate limited." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:884(td) -msgid "account_blacklist" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:886(td) -msgid "Comma separated lists of account names that will not be allowed. Returns a 497 response." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:889(td) -msgid "container_ratelimit_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:891(td) -msgid "When set with container_limit_x = r: for containers of size x, limit requests per second to r. Will limit GET and HEAD requests to /account_name/container_name and PUTs and DELETEs to /account_name/container_name/object_name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:901(para) -msgid "The container rate limits are linearly interpolated from the values given. A sample container rate limiting could be:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:903(para) -msgid "container_ratelimit_100 = 100" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:904(para) -msgid "container_ratelimit_200 = 50" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:905(para) -msgid "container_ratelimit_500 = 20" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:906(para) -msgid "This would result in" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:908(caption) -msgid "Values for Rate Limiting with Sample Configuration Settings" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:910(td) -msgid "Container Size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:911(td) -msgid "Rate Limit" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:913(td) -msgid "0-99" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:914(td) -msgid "No limiting" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:916(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:917(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:723(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1026(td) -msgid "100" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:920(td) -msgid "150" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:921(td) -msgid "75" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:923(td) -msgid "500" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:924(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:927(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:416(td) -msgid "20" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:936(title) -msgid "Additional Features" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:937(para) -msgid "This section aims to detail a number of additional features in Swift and their configuration." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:941(title) -msgid "Health Check" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:942(para) -msgid "Health Check provides a simple way to monitor if the swift proxy server is alive. If the proxy is access with the path /healthcheck, it will respond with “OK” in the body, which can be used by monitoring tools." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:948(caption) -msgid "Configuration options for filter:healthcheck in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:957(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:992(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1048(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:78(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:151(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:237(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:344(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:395(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:467(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:581(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:625(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:672(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:742(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:798(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:835(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:970(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1005(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1088(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1131(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1243(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1337(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1401(td) -msgid "log_name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:958(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:993(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1049(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:79(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:94(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:172(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:545(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:582(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:913(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1208(td) -msgid "swift" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:959(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:994(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1050(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:80(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:153(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:239(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:346(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:397(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:583(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:627(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:674(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:744(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:800(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:837(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:972(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1007(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1090(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1133(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1245(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1339(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1403(td) -msgid "Label used when logging" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:962(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:997(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1053(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:83(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:156(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:242(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:349(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:400(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:457(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:586(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:630(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:677(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:747(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:803(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:840(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:975(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1010(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1093(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1136(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1248(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1342(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1406(td) -msgid "log_facility" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:963(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:998(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1054(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:84(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:157(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:243(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:350(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:401(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:458(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:483(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:587(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:631(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:678(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:748(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:804(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:841(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:976(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1011(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1094(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1137(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1249(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1343(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1407(td) -msgid "LOG_LOCAL0" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:964(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:999(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1055(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:85(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:158(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:244(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:351(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:402(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:588(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:632(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:679(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:749(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:805(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:842(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:977(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1012(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1095(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1138(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1250(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1344(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1408(td) -msgid "Syslog log facility" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:967(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1002(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1058(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:88(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:161(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:247(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:354(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:405(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:462(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:591(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:635(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:682(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:752(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:808(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:845(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:980(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1015(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1098(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1141(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1253(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1347(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1411(td) -msgid "log_level" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:968(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1003(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1059(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:89(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:162(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:248(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:355(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:406(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:463(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:592(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:636(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:683(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:753(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:809(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:846(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:981(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1016(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1099(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1142(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1254(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1348(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1412(td) -msgid "INFO" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:969(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1004(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1060(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:90(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:163(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:249(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:356(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:407(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:593(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:637(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:684(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:754(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:810(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:847(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:982(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1017(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1100(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1143(td) -msgid "Logging level" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:977(title) -msgid "Domain Remap" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:978(para) -msgid "Domain Remap is middleware that translates container and account parts of a domain to path parameters that the proxy server understands." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:983(caption) -msgid "Configuration options for filter:domain_remap in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1007(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1063(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:472(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1258(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1352(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1416(td) -msgid "log_headers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1008(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1064(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1417(td) -msgid "False" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1009(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1065(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1260(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1354(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1418(td) -msgid "If True, log headers in each request" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1012(td) -msgid "path_root" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1013(td) -msgid "v1" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1014(td) -msgid "Root path" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1017(td) -msgid "reseller_prefixes" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1018(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1358(td) -msgid "AUTH" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1019(td) -msgid "Reseller prefix" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1022(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1073(td) -msgid "storage_domain" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1023(td) -msgid "example.com" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1024(td) -msgid "Domain to use for remap" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1032(title) -msgid "CNAME Lookup" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1033(para) -msgid "CNAME Lookup is middleware that translates an unknown domain in the host header to something that ends with the configured storage_domain by looking up the given domain's CNAME record in DNS." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1039(caption) -msgid "Configuration options for filter:cname_lookup in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1068(td) -msgid "lookup_depth" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1069(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1382(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:62(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:265(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:365(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:540(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:908(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1203(td) -msgid "1" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1070(td) -msgid "As CNAMEs can be recursive, how many levels to search through." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1074(td) -msgid "example.conf" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1081(title) -msgid "Temporary URL" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1082(para) -msgid "Allows the creation of URLs to provide temporary access to objects. For example, a website may wish to provide a link to download a large object in Swift, but the Swift account has no public access. The website can generate a URL that will provide GET access for a limited time to the resource. When the web browser user clicks on the link, the browser will download the object directly from Swift, obviating the need for the website to act as a proxy for the request. If the user were to share the link with all his friends, or accidentally post it on a forum, etc. the direct access would be limited to the expiration time set when the website created the link. To create such temporary URLs, first an X-Account-Meta-Temp-URL-Key header must be set on the Swift account. Then, an HMAC-SHA1 (RFC 2104) signature is generated using the HTTP method to allow (GET or PUT), the Unix timestamp the access should be allowed until, the full path to the object, and the key set on the account. For example, here is code generating the signature for a GET for 60 seconds on /v1/AUTH_account/container/object: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1116(para) -msgid "Be certain to use the full path, from the /v1/ onward. Let's say the sig ends up equaling da39a3ee5e6b4b0d3255bfef95601890afd80709 and expires ends up 1323479485. Then, for example, the website could provide a link to: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1126(para) -msgid "Any alteration of the resource path or query arguments would result in 401 Unauthorized. Similary, a PUT where GET was the allowed method would 401. HEAD is allowed if GET or PUT is allowed. Using this in combination with browser form post translation middleware could also allow direct-from-browser uploads to specific locations in Swift. Note that changing the X-Account-Meta-Temp-URL-Key will invalidate any previously generated temporary URLs within 60 seconds (the memcache time for the key)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1139(caption) -msgid "Configuration options for filter:tempurl in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1148(td) -msgid "incoming_allow_headers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1153(td) -msgid "incoming_remove_headers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1154(td) -msgid "x-timestamp" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1158(td) -msgid "outgoing_allow_headers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1159(td) -msgid "x-object-meta-public-*" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1163(td) -msgid "outgoing_remove_headers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1164(td) -msgid "x-object-meta-*" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1172(title) -msgid "Name Check Filter" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1173(para) -msgid "Name Check is a filter that disallows any paths that contain defined forbidden characters or that exceed a defined length." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1177(caption) -msgid "Configuration options for filter:name_check in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1186(td) -msgid "forbidden_chars" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1188(td) -msgid "Characters that are not allowed in a name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1191(td) -msgid "max_length" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1192(td) -msgid "255" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1193(td) -msgid "Maximum length of a name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1196(td) -msgid "forbidden_regexp" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1197(td) -msgid "\"/\\./|/\\.\\./|/\\.$|/\\.\\.$\"" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1198(td) -msgid "Substrings to forbid, using regular expression syntax" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1205(title) -msgid "Constraints" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1206(para) -msgid "The swift-constraints section in swift.conf allows modification of internal limits within swift. These are advanced features for tuning the performance of the cluster and should be altered with caution." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1208(caption) -msgid "Configuration options for swift-constraints in swift.conf" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1216(td) -msgid "max_file_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1217(td) -msgid "5368709122" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1218(td) -msgid "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)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1226(td) -msgid "max_meta_name_length" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1227(td) -msgid "128" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1228(td) -msgid "the max number of bytes in the utf8 encoding of the name portion of a metadata header." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1232(td) -msgid "max_meta_value_lenth" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1233(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1259(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1264(td) -msgid "256" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1234(td) -msgid "the max number of bytes in the utf8 encoding of a metadata value" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1237(td) -msgid "max_meta_count" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1238(td) -msgid "90" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1239(td) -msgid "the max number of metadata keys that can be stored on a single account, container, or object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1243(td) -msgid "max_meta_overall_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1244(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:67(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:603(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:918(td) -msgid "4096" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1245(td) -msgid "the max number of bytes in the utf8 encoding of the metadata (keys + values)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1248(td) -msgid "max_object_name_length" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1249(td) -msgid "1024" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1250(td) -msgid "the max number of bytes in the utf8 encoding of an object name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1253(td) -msgid "container_listing_limit" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1254(td) -msgid "10000" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1255(td) -msgid "the default (and max) number of items returned for a container listing request" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1258(td) -msgid "max_account_name_length" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1260(td) -msgid "the max number of bytes in the utf8 encoding of an account name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1263(td) -msgid "max_container_name_length" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1265(td) -msgid "the max number of bytes in the utf8 encoding of a container name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1272(title) -msgid "Cluster Health" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1273(para) -msgid "There is a swift-dispersion-report tool for measuring overall cluster health. This is accomplished by checking if a set of deliberately distributed containers and objects are currently in their proper places within the cluster. For instance, a common deployment has three replicas of each object. The health of that object can be measured by checking if each replica is in its proper place. If only 2 of the 3 is in place the object’s heath can be said to be at 66.66%, where 100% would be perfect. A single object’s health, especially an older object, usually reflects the health of that entire partition the object is in. If we make enough objects on a distinct percentage of the partitions in the cluster, we can get a pretty valid estimate of the overall cluster health. In practice, about 1% partition coverage seems to balance well between accuracy and the amount of time it takes to gather results. The first thing that needs to be done to provide this health value is create a new account solely for this usage. Next, we need to place the containers and objects throughout the system so that they are on distinct partitions. The swift-dispersion-populate tool does this by making up random container and object names until they fall on distinct partitions. Last, and repeatedly for the life of the cluster, we need to run the swift-dispersion-report tool to check the health of each of these containers and objects. These tools need direct access to the entire cluster and to the ring files (installing them on a proxy server will probably do). Both swift-dispersion-populate and swift-dispersion-report use the same configuration file, /etc/swift/dispersion.conf. Example dispersion.conf file: There are also options for the conf file for specifying the dispersion coverage (defaults to 1%), retries, concurrency, etc. though usually the defaults are fine. Once the configuration is in place, run swift-dispersion-populate to populate the containers and objects throughout the cluster. Now that those containers and objects are in place, you can run swift-dispersion-report to get a dispersion report, or the overall health of the cluster. Here is an example of a cluster in perfect health: Now, deliberately double the weight of a device in the object ring (with replication turned off) and rerun the dispersion report to show what impact that has: You can see the health of the objects in the cluster has gone down significantly. Of course, this test environment has just four devices, in a production environment with many many devices the impact of one device change is much less. Next, run the replicators to get everything put back into place and then rerun the dispersion report: Alternatively, the dispersion report can also be output in json format. This allows it to be more easily consumed by third party utilities: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1367(caption) -msgid "Configuration options for dispersion in proxy-server.conf file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1376(td) -msgid "auth_version" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1377(td) -msgid "1.0" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1378(td) -msgid "Swift authentication API version" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1381(td) -msgid "dispersion_coverage" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1386(td) -msgid "dump_json" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1387(td) -msgid "'no'" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1391(td) -msgid "retries" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1392(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:177(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:768(td) -msgid "3" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1396(td) -msgid "auth_url" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1401(td) -msgid "auth_user" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1406(td) -msgid "auth_key" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1411(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:28(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:508(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:876(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1197(td) -msgid "swift_dir" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1412(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:29(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:509(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:877(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1198(td) -msgid "/etc/swift" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1425(title) -msgid "Configuring Object Storage with the S3 API" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1426(para) -msgid "The Swift3 middleware emulates the S3 REST API on top of Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1428(para) -msgid "The following operations are currently supported:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1431(para) -msgid "GET Service" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1432(para) -msgid "DELETE Bucket" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1433(para) -msgid "GET Bucket (List Objects)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1434(para) -msgid "PUT Bucket" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1435(para) -msgid "DELETE Object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1436(para) -msgid "GET Object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1437(para) -msgid "HEAD Object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1438(para) -msgid "PUT Object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1439(para) -msgid "PUT Object (Copy)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1440(para) -msgid "To use this middleware, first download the latest version from its repository to your proxy server(s)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1443(para) -msgid "Optional: To use this middleware with Swift 1.7.0 and previous versions, you'll need to use the v1.7 tag of the fujita/swift3 repository. Clone the repo as above and then:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1446(para) -msgid "Then, install it using standard python mechanisms, such as:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1448(para) -msgid "Alternatively, if you have configured the Ubuntu Cloud Archive, you may use: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1450(para) -msgid "To add this middleware to your configuration, add the swift3 middleware in front of the auth middleware, and before any other middleware that look at swift requests (like rate limiting)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1454(para) -msgid "Ensure that your proxy-server.conf file contains swift3 in the pipeline and the [filter:swift3] section, as shown below:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1463(para) -msgid "Next, configure the tool that you use to connect to the S3 API. For S3curl, for example, you'll need to add your host IP information by adding y our host IP to the @endpoints array (line 33 in s3curl.pl):" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1468(para) -msgid "Now you can send commands to the endpoint, such as:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1472(para) -msgid "To set up your client, the access key will be the concatenation of the account and user strings that should look like test:tester, and the secret access key is the account password. The host should also point to the Swift storage node's hostname. It also will have to use the old-style calling format, and not the hostname-based container format. Here is an example client setup using the Python boto library on a locally installed all-in-one Swift installation." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1490(title) -msgid "Managing OpenStack Object Storage with CLI Swift" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1490(para) -msgid "In the Object Store (swift) project there is a tool that can perform a variety of tasks on your storage cluster named swift. This client utility can be used for adhoc processing, to gather statistics, list items, update metadata, upload, download and delete files. It is based on the native swift client library client.py. Incorporating client.py into swift provides many benefits such as seamlessly re-authorizing if the current token expires in the middle of processing, retrying operations up to five times and a processing concurrency of 10. All of these things help make the swift tool robust and great for operational use." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1499(title) -msgid "Swift ACLs" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1500(para) -msgid "Swift ACLs work with users and accounts. Users have roles on accounts - such as '.admin', which allows full access to all containers and objects under the account. ACLs are set at the container level and support lists for read and write access, which are set with the X-Container-Read and X-Container-Write header respectively." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1507(para) -msgid "The swift client can be used to set the acls, using the post subcommand with the option '-r' for the read ACL, and '-w' for the write ACL. This example allows the user 'testuser' to read objects in the container: This could instead be a list of users." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1516(para) -msgid "If you are using the StaticWeb middleware to allow OpenStack Object Storage to serve public web content, you should also be aware of the ACL syntax for managing allowed referrers. The syntax is '.r:' followed by a list of allowed referrers. For example, this command allows all referring domains access to the object: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1529(title) -msgid "Swift CLI Basics" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1530(para) -msgid "The command line usage for swift, the CLI tool is: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1533(para) -msgid "Here are the available commands for swift." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1534(title) -msgid "stat [container] [object]" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1535(para) -msgid "Displays information for the account, container, or object depending on the args given (if any)." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1537(title) -msgid "list [options] [container]" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1538(para) -msgid "Lists the containers for the account or the objects for a container. -p or -prefix is an option that will only list items beginning with that prefix. -d or -delimiter is option (for container listings only) that will roll up items with the given delimiter, or character that can act as a nested directory organizer." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1543(title) -msgid "upload [options] container file_or_directory [file_or_directory] […]" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1543(para) -msgid "Uploads to the given container the files and directories specified by the remaining args. -c or -changed is an option that will only upload files that have changed since the last upload." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1546(title) -msgid "post [options] [container] [object]" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1547(para) -msgid "Updates meta information for the account, container, or object depending on the args given. If the container is not found, it will be created automatically; but this is not true for accounts and objects. Containers also allow the -r (or -read-acl) and -w (or -write-acl) options. The -m or -meta option is allowed on all and used to define the user meta data items to set in the form Name:Value. This option can be repeated." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1553(para) -msgid "Example: post -m Color:Blue -m Size:Large" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1554(title) -msgid "download —all OR download container [object] [object] …" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1555(para) -msgid "Downloads everything in the account (with —all), or everything in a container, or a list of objects depending on the args given. For a single object download, you may use the -o [—output] (filename) option to redirect the output to a specific file or if “-” then just redirect to stdout." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1560(title) -msgid "delete —all OR delete container [object] [object] …" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1561(para) -msgid "Deletes everything in the account (with —all), or everything in a container, or a list of objects depending on the args given." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1564(para) -msgid "Example: swift -A https://auth.api.rackspacecloud.com/v1.0 -U user -K key stat" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1566(title) -msgid "Options for swift" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1567(para) -msgid "-version show program’s version number and exit" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1568(para) -msgid "-h, -help show this help message and exit" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1569(para) -msgid "-s, -snet Use SERVICENET internal network" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1570(para) -msgid "-v, -verbose Print more info" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1571(para) -msgid "-q, -quiet Suppress status output" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1572(para) -msgid "-A AUTH, -auth=AUTH URL for obtaining an auth token" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1573(para) -msgid "-U USER, -user=USER User name for obtaining an auth token" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1574(para) -msgid "-K KEY, -key=KEY Key for obtaining an auth token" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1576(title) -msgid "Analyzing Log Files with Swift CLI" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1577(para) -msgid "When you want quick, command-line answers to questions about logs, you can use swift with the -o or -output option. The -o —output option can only be used with a single object download to redirect the data stream to either a different file name or to STDOUT (-). The ability to redirect the output to STDOUT allows you to pipe “|” data without saving it to disk first. One common use case is being able to do some quick log file analysis. First let’s use swift to setup some data for the examples. The “logtest” directory contains four log files with the following line format." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1597(para) -msgid "The swift tool can easily upload the four log files into a container named “logtest”:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1599(para) -msgid " Get statistics on the account: Get statistics on the container: List all the objects in the container: " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1633(para) -msgid "These next three examples use the -o —output option with (-) to help answer questions about the uploaded log files. The swift command will download an object, stream it to awk to determine the breakdown of requests by return code for everything during 2200 on November 16th, 2010. Based on the log line format column 9 is the type of request and column 12 is the return code. After awk processes the data stream it is piped to sort and then uniq -c to sum up the number of occurrences for each combination of request type and return code." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1677(para) -msgid "This example uses a bash for loop with awk, swift with its -o —output option with a hyphen (-) to find out how many PUT requests are in each log file. First create a list of objects by running swift with the list command on the “logtest” container; then for each item in the list run swift with download -o - then pipe the output into grep to filter the put requests and finally into wc -l to count the lines." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1695(para) -msgid "By adding the -p —prefix option a prefix query is performed on the list to return only the object names that begin with a specific string. Let’s determine out how many PUT requests are in each object with a name beginning with “2010-11-15”. First create a list of objects by running swift with the list command on the “logtest” container with the prefix option -p 2010-11-15. Then on each of item(s) returned run swift with the download -o - then pipe the output to grep and wc as in the previous example. The echo command is added to display the object name." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml:1711(para) -msgid "The swift utility is simple, scalable, flexible and provides useful solutions all of which are core principles of cloud computing; with the -o output option being just one of its many features." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:5(title) -msgid "OpenStack Object Storage Monitoring" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:7(para) -msgid "Excerpted from a blog post by Darrell Bishop" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:10(para) -msgid "An OpenStack Object Storage cluster is a complicated beast—a collection of many daemons across many nodes, all working together. With so many “moving parts” it’s important to be able to tell what’s going on inside the cluster. Tracking server-level metrics like CPU utilization, load, memory consumption, disk usage and utilization, etc. is necessary, but not sufficient. We need to know what the different daemons are doing on each server. What’s the volume of object replication on node8? How long is it taking? Are there errors? If so, when did they happen?" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:20(para) -msgid "In such a complex ecosystem, it’s no surprise that there are multiple approaches to getting the answers to these kinds of questions. Let’s examine some of the existing approaches to OpenStack Object Storage monitoring." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:25(title) -msgid "Swift Recon" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:26(para) -msgid "The Swift Recon middleware can provide general machine stats (load average, socket stats, /proc/meminfo contents, etc.) as well as Swift-specific metrics:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:34(para) -msgid "The MD5 sum of each ring file." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:37(para) -msgid "The most recent object replication time." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:40(para) -msgid "Count of each type of quarantined file: account, container, or object." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:44(para) -msgid "Count of “async_pendings” (deferred container updates) on disk." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:48(para) -msgid "Swift Recon is middleware installed in the object server’s pipeline and takes one required option: a local cache directory. Tracking of async_pendings requires an additional cron job per object server. Data is then accessed by sending HTTP requests to the object server directly, or by using the swift-recon command-line tool." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:55(para) -msgid "There are some good Object Storage cluster stats in there, but the general server metrics overlap with existing server monitoring systems and to get the Swift-specific metrics into a monitoring system, they must be polled. Swift Recon is essentially acting as a middle-man metrics collector. The process actually feeding metrics to your stats system, like collectd, gmond, etc., is probably already running on the storage node. So it could either talk to Swift Recon or just collect the metrics itself." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:65(para) -msgid "There’s an upcoming update to Swift Recon which broadens support to the account and container servers. The auditors, replicators, and updaters can also report statistics, but only for the most recent run." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:73(title) -msgid "Swift-Informant" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:74(para) -msgid "Florian Hines developed the Swift-Informant middleware to get real-time visibility into Object Storage client requests. It sits in the proxy server’s pipeline and after each request to the proxy server, sends three metrics to a StatsD server:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:83(para) -msgid "A counter increment for a metric like obj.GET.200 or cont.PUT.404." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:85(para) -msgid "Timing data for a metric like acct.GET.200 or obj.GET.200. [The README says the metrics will look like duration.acct.GET.200, but I don’t see the “duration” in the code. I’m not sure what Etsy’s server does, but our StatsD server turns timing metrics into 5 derivative metrics with new segments appended, so it probably works as coded. The first metric above would turn into acct.GET.200.lower, acct.GET.200.upper, acct.GET.200.mean, acct.GET.200.upper_90, and acct.GET.200.count]" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:91(para) -msgid "A counter increase by the bytes transferred for a metric like tfer.obj.PUT.201." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:93(para) -msgid "This is good for getting a feel for the quality of service clients are experiencing with the timing metrics, as well as getting a feel for the volume of the various permutations of request server type, command, and response code. Swift-Informant also requires no change to core Object Storage code since it is implemented as middleware. However, because of this, it gives you no insight into the workings of the cluster past the proxy server. If one storage node’s responsiveness degrades for some reason, you’ll only see that some of your requests are bad—either as high latency or error status codes. You won’t know exactly why or where that request tried to go. Maybe the container server in question was on a good node, but the object server was on a different, poorly-performing node." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:111(title) -msgid "Statsdlog" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:112(para) -msgid "Florian’s Statsdlog project increments StatsD counters based on logged events. Like Swift-Informant, it is also non-intrusive, but statsdlog can track events from all Object Storage daemons, not just proxy-server. The daemon listens to a UDP stream of syslog messages and StatsD counters are incremented when a log line matches a regular expression. Metric names are mapped to regex match patterns in a JSON file, allowing flexible configuration of what metrics are extracted from the log stream." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:123(para) -msgid "Currently, only the first matching regex triggers a StatsD counter increment, and the counter is always incremented by 1. There’s no way to increment a counter by more than one or send timing data to StatsD based on the log line content. The tool could be extended to handle more metrics per line and data extraction, including timing data. But even then, there would still be a coupling between the log textual format and the log parsing regexes, which would themselves be more complex in order to support multiple matches per line and data extraction. Also, log processing introduces a delay between the triggering event and sending the data to StatsD. We would prefer to increment error counters where they occur, send timing data as soon as it is known, avoid coupling between a log string and a parsing regex, and not introduce a time delay between events and sending data to StatsD. And that brings us to the next method of gathering Object Storage operational metrics." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:143(title) -msgid "Swift StatsD Logging" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:144(para) -msgid "StatsD was designed for application code to be deeply instrumented; metrics are sent in real-time by the code which just noticed something or did something. The overhead of sending a metric is extremely low: a sendto of one UDP packet. If that overhead is still too high, the StatsD client library can send only a random portion of samples and StatsD will approximate the actual number when flushing metrics upstream." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:145(para) -msgid "To avoid the problems inherent with middleware-based monitoring and after-the-fact log processing, the sending of StatsD metrics is integrated into Object Storage itself. The submitted change set currently reports 124 metrics across 15 Object Storage daemons and the tempauth middleware. Details of the metrics tracked are in the Swift Administration Guide." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:156(para) -msgid "The sending of metrics is integrated with the logging framework. To enable, configure log_statsd_host in the relevant config file. You can also specify the port and a default sample rate. The specified default sample rate is used unless a specific call to a statsd logging method (see the list below) overrides it. Currently, no logging calls override the sample rate, but it’s conceivable that some metrics may require accuracy (sample_rate == 1) while others may not." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:162(para) -msgid "Then the LogAdapter object returned by get_logger(), usually stored in self.logger, has the following new methods:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:164(para) -msgid "set_statsd_prefix(self, prefix) Sets the client library’s stat prefix value which gets prepended to every metric. The default prefix is the “name” of the logger (eg. “object-server”, “container-auditor”, etc.). This is currently used to turn “proxy-server” into one of “proxy-server.Account”, “proxy-server.Container”, or “proxy-server.Object” as soon as the Controller object is determined and instantiated for the request." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:165(para) -msgid "update_stats(self, metric, amount, sample_rate=1) Increments the supplied metric by the given amount. This is used when you need to add or subtract more that one from a counter, like incrementing “suffix.hashes” by the number of computed hashes in the object replicator." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:166(para) -msgid "increment(self, metric, sample_rate=1) Increments the given counter metric by one." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:167(para) -msgid "decrement(self, metric, sample_rate=1) Lowers the given counter metric by one." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:168(para) -msgid "timing(self, metric, timing_ms, sample_rate=1) Record that the given metric took the supplied number of milliseconds." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:169(para) -msgid "timing_since(self, metric, orig_time, sample_rate=1) Convenience method to record a timing metric whose value is “now” minus an existing timestamp." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:171(para) -msgid "Note that these logging methods may safely be called anywhere you have a logger object. If StatsD logging has not been configured, the methods are no-ops. This avoids messy conditional logic each place a metric is recorded. Here’s two example usages of the new logging methods:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragemonitoring.xml:215(para) -msgid "The development team of StatsD wanted to use the pystatsd client library (not to be confused with a similar-looking project also hosted on GitHub), but the released version on PyPi was missing two desired features the latest version in GitHub had: the ability to configure a metrics prefix in the client object and a convenience method for sending timing data between “now” and a “start” timestamp you already have. So they just implemented a simple StatsD client library from scratch with the same interface. This has the nice fringe benefit of not introducing another external library dependency into Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:6(title) -msgid "Server Configuration Reference" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:7(para) -msgid "Swift uses paste.deploy to manage server configurations. Default configuration options are set in the [DEFAULT] section, and any options specified there can be overridden in any of the other sections." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:11(title) -msgid "Object Server Configuration" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:12(para) -msgid "An example Object Server configuration can be found at etc/object-server.conf-sample in the source code repository." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:15(para) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:498(para) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:866(para) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1172(para) -msgid "The following configuration options are available:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:19(caption) -msgid "object-server.conf Default Options in the [DEFAULT] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:30(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:510(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:878(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1199(td) -msgid "Swift configuration directory" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:33(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:513(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:881(td) -msgid "devices" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:34(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:514(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:882(td) -msgid "/srv/node" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:35(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:515(td) -msgid "Parent directory of where devices are mounted" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:39(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:518(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:886(td) -msgid "mount_check" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:40(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:99(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:519(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:550(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:641(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:887(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:923(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:986(td) -msgid "true" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:41(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:520(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:888(td) -msgid "Whether or not check if the devices are mounted to prevent accidentally writing to the root device" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:46(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:524(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:892(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1182(td) -msgid "bind_ip" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:47(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:525(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:893(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1183(td) -msgid "0.0.0.0" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:48(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:526(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:894(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1184(td) -msgid "IP Address for server to bind to" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:51(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:529(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:897(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1187(td) -msgid "bind_port" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:52(td) -msgid "6000" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:53(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:531(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:899(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1189(td) -msgid "Port for server to bind to" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:56(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:534(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:902(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1192(td) -msgid "bind_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:57(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:259(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:316(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:535(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:698(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:718(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:903(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1038(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1063(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1193(td) -msgid "30" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:58(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:536(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:904(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1194(td) -msgid "Seconds to attempt bind before giving up" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:61(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:539(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:907(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1202(td) -msgid "workers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:63(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:541(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:909(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1204(td) -msgid "Number of workers to fork" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:66(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:602(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:917(td) -msgid "backlog" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:68(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:604(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:919(td) -msgid "Maximum number of allowed pending TCP connections." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:72(td) -msgid "expiring_objects_container_divisor" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:73(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:198(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1376(td) -msgid "86400" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:93(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:171(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:544(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:912(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1207(td) -msgid "user" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:95(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:173(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:546(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:914(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1209(td) -msgid "User to run as" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:98(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:549(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:922(td) -msgid "db_preallocation" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:100(td) -msgid "Preallocate disk space for new SQLite databases to decrease fragmentation" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:104(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:554(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:927(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1222(td) -msgid "eventlet_debug" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:105(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:110(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:555(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:560(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:646(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:928(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:933(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1223(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1315(td) -msgid "false" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:106(td) -msgid "Turn on debug logging for eventlet" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:109(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:559(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:932(td) -msgid "disable_fallocate" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:111(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:561(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:934(td) -msgid "Disable \"fast fail\" fallocate checks if the underlying filesystem does not support it." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:116(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:564(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:937(td) -msgid "fallocate_reserve" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:118(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:566(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:939(td) -msgid "The number of bytes for fallocate to reserve, whether there is space for the given file size or not. The default fallocate_reserve is 0, meaning \"no reserve\". Some systems behave badly when they completely run out of space. To alleviate this problem, you can set fallocate_reserve. When the disk free space falls at or below this amount, fallocate calls will fail, even if the underlying OS fallocate call would succeed. For example, a fallocate_reserve of 10737418240 (10G) would make all fallocate calls fail, even for zero-byte files, when the disk free space falls under 10G." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:135(caption) -msgid "object-server.conf Server Options in the [object-server] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:144(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:618(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:964(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1237(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1330(td) -msgid "use" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:148(code) -msgid "egg:swift#object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:146(td) -msgid "The paste.deploy entry point for the object server. For most cases, this should be ." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:152(td) -msgid "object-server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:166(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:640(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:985(td) -msgid "log_requests" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:167(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1259(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1353(td) -msgid "True" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:168(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:642(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:987(td) -msgid "Whether or not to log each request" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:176(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:369(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:652(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:702(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:767(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1042(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1156(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1288(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1380(td) -msgid "node_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:178(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:371(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:654(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:704(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:769(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1044(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1158(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1290(td) -msgid "Request timeout to external services" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:181(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:374(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:657(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:707(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:772(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1047(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1161(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1298(td) -msgid "conn_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:182(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:375(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:658(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:708(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:773(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1048(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1162(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1299(td) -msgid "0.5" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:183(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:376(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:659(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:709(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:774(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1049(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1163(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1300(td) -msgid "Connection timeout to external services" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:186(td) -msgid "network_chunk_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:187(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:193(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1274(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1279(td) -msgid "65536" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:188(td) -msgid "Size of chunks to read/write over the network" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:192(td) -msgid "disk_chunk_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:194(td) -msgid "Size of chunks to read/write to disk" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:197(td) -msgid "max_upload_time" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:199(td) -msgid "Maximum time allowed to upload an object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:202(td) -msgid "slow" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:204(td) -msgid "If > 0, Minimum time in seconds for a PUT or DELETE request to complete" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:208(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:596(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:990(td) -msgid "auto_create_account_prefix" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:209(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:597(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:991(td) -msgid "." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:210(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:598(td) -msgid "Prefix used when automatically creating accounts" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:214(td) -msgid "allowed_headers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:215(td) -msgid "content-disposition, content-encoding, x-delete-at, x-object-manifest," -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:217(td) -msgid "Comma-separated list of headers that can be set in metadata of an object" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:221(td) -msgid "mb_per_sync" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:222(td) -msgid "512" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:223(td) -msgid "On PUTs, sync data every n MB" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:228(caption) -msgid "object-server.conf Replicator Options in the [object-replicator] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:238(td) -msgid "object-replicator" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:252(td) -msgid "daemonize" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:253(td) -msgid "yes" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:254(td) -msgid "Whether or not to run replication as a daemon" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:258(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:697(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1037(td) -msgid "run_pause" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:260(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:699(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1039(td) -msgid "Time in seconds to wait between replication passes" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:264(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:364(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:692(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:762(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1032(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1146(td) -msgid "concurrency" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:266(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:694(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1034(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1148(td) -msgid "Number of replication workers to spawn" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:269(td) -msgid "timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:270(td) -msgid "5" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:271(td) -msgid "Timeout value sent to rsync –timeout and –contimeout options" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:275(td) -msgid "http_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:277(td) -msgid "Maximum duration for an HTTP request" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:280(td) -msgid "lockup_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:281(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:814(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1104(td) -msgid "1800" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:282(td) -msgid "Attempts to kill all workers if nothing replicates for lockup_timeout seconds." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:286(td) -msgid "stats_interval" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:287(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:360(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:453(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:758(td) -msgid "300" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:288(td) -msgid "Interval in seconds between logging replication statistics" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:292(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:712(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1052(td) -msgid "reclaim_age" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:293(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:713(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1053(td) -msgid "604800" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:294(td) -msgid "Time elapsed in seconds before an object can be reclaimed" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:298(td) -msgid "recon_cache_path" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:299(td) -msgid "/var/cache/swift" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:300(td) -msgid "Directory where stats for a few items will be stored" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:304(td) -msgid "recon_enable" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:305(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:328(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:728(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1058(td) -msgid "no" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:306(td) -msgid "Enable logging of replication stats for recon" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:310(td) -msgid "ring_check_interval" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:311(td) -msgid "15" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:312(td) -msgid "How often (in seconds) to check the ring" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:315(td) -msgid "rsync_io_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:317(td) -msgid "Passed to rsync for max duration (seconds) of an I/O op" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:321(td) -msgid "rsync_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:322(td) -msgid "900" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:323(td) -msgid "Max duration (seconds) of a partition rsync" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:327(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:727(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1057(td) -msgid "vm_test_mode" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:329(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:729(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1059(td) -msgid "Indicates that you are using a VM environment" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:335(caption) -msgid "object-server.conf Updater Options in the [object-updater] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:345(td) -msgid "object-updater" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:359(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:717(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:757(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:813(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1062(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1103(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1151(td) -msgid "interval" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:361(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:759(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:815(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1064(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1105(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1153(td) -msgid "Minimum time for a pass to take" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:366(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:764(td) -msgid "Number of updater workers to spawn" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:370(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:653(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:703(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1043(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1074(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1157(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1289(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1310(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1381(td) -msgid "10" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:379(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:777(td) -msgid "slowdown" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:380(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:778(td) -msgid "0.01" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:381(td) -msgid "Time in seconds to wait between objects" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:386(caption) -msgid "object-server.conf Auditor Options in the [object-auditor] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:396(td) -msgid "object-auditor" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:410(td) -msgid "log_time" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:411(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1152(td) -msgid "3600" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:412(td) -msgid "Frequency of status logs in seconds." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:415(td) -msgid "files_per_second" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:417(td) -msgid "Maximum files audited per second. Should be tuned according to individual system specs. 0 is unlimited." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:422(td) -msgid "bytes_per_second" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:423(td) -msgid "10000000" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:424(td) -msgid "Maximum bytes audited per second. Should be tuned according to individual system specs. 0 is unlimited." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:429(td) -msgid "zero_byte_files_per_second" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:430(td) -msgid "50" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:431(td) -msgid "Maximum zero byte files audited per second." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:438(para) -msgid "When configured, the StaticWeb WSGI middleware serves container data as a static web site with index file and error file resolution and optional file listings. This mode is normally only active for anonymous requests." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:443(caption) -msgid "object-server.conf staticweb Options in the [filter:staticweb] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:452(td) -msgid "cache_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:454(td) -msgid "Number of seconds to cache container x-container-meta-web-* header values." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:459(td) -msgid "Indicate which facility to use for logging staticweb requests." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:464(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:469(td) -msgid "Indicate which level of logging to use for staticweb requests." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:468(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:488(td) -msgid "staticweb" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:473(td) -msgid "f" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:474(td) -msgid "Indicate which headers to use for logging staticweb requests." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:477(td) -msgid "access_log_level" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:478(td) -msgid "'INFO'" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:479(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:489(td) -msgid "Indicate which level of logging to use for staticweb container access." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:482(td) -msgid "access_log_facility" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:484(td) -msgid "Indicate which facility to use for logging access to staticweb containers." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:487(td) -msgid "access_log_name" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:495(title) -msgid "Container Server Configuration" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:496(para) -msgid "An example Container Server configuration can be found at etc/container-server.conf-sample in the source code repository." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:500(caption) -msgid "container-server.conf Default Options in the [DEFAULT] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:530(td) -msgid "6001" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:551(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:924(td) -msgid "preallocate disk space for new SQLite databases to decrease fragmentation" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:556(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:929(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1224(td) -msgid "turn on debug logging for eventlet" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:610(caption) -msgid "container-server.conf Server Options in the [container-server] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:622(code) -msgid "egg:swift#container" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:620(td) -msgid "The paste.deploy entry point for the container server. For most cases, this should be ." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:626(td) -msgid "container-server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:645(td) -msgid "allow_versions" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:647(td) -msgid "Whether to allow versions of containers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:664(caption) -msgid "container-server.conf Replicator Options in the [container-replicator] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:673(td) -msgid "container-replicator" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:687(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1020(td) -msgid "per_diff" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:689(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1022(td) -msgid "Limit number of items to get per diff" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:693(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1033(td) -msgid "8" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:714(td) -msgid "Time elapsed in seconds before a container can be reclaimed" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:719(td) -msgid "Minimum time for a pass to take (s)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:722(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1025(td) -msgid "max_diffs" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:724(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1027(td) -msgid "Caps how long the replicator spends trying to sync a database per pass" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:734(caption) -msgid "container-server.conf Updater Options in the [container-updater] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:743(td) -msgid "container-updater" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:763(td) -msgid "4" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:779(td) -msgid "Time in seconds to wait between containers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:782(td) -msgid "account_supression_time" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:784(td) -msgid "Seconds to suppress updating an account that has generated an error (timeout, not yet found, etc.)" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:790(caption) -msgid "container-server.conf Auditor Options in the [container-auditor] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:799(td) -msgid "container-auditor" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:818(td) -msgid "containers_per_second" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:819(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1109(td) -msgid "200" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:820(td) -msgid "Maximum containers audited per second. Should be tuned according to individual system specs. 0 is unlimited." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:827(caption) -msgid "container-server.conf Sync Options in the [container-sync] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:836(td) -msgid "container-sync" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:850(td) -msgid "container_time" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:852(td) -msgid "Maximum amount of time to spend syncing each container" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:855(td) -msgid "sync_proxy" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:857(td) -msgid "If you need to use an HTTP Proxy, set it here (eg http://127.0.0.1:8888); defaults to no proxy." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:863(title) -msgid "Account Server Configuration" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:864(para) -msgid "An example Account Server configuration can be found at etc/account-server.conf-sample in the source code repository." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:868(caption) -msgid "account-server.conf Default Options in the [DEFAULT] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:883(td) -msgid "Parent directory or where devices are mounted" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:898(td) -msgid "6002" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:956(caption) -msgid "account-server.conf Server Options in the [account-server] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:967(code) -msgid "egg:swift#account" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:966(td) -msgid "Entry point for paste.deploy for the account server. For most cases, this should be ." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:971(td) -msgid "account-server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:992(td) -msgid "prefix used when automatically creating accounts" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:997(caption) -msgid "account-server.conf Replicator Options in the [account-replicator] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1006(td) -msgid "account-replicator" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1054(td) -msgid "Time elapsed in seconds before an account can be reclaimed" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1067(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1303(td) -msgid "error_suppression_interval" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1069(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1305(td) -msgid "Time in seconds that must elapse since the last error for a node to be considered no longer error limited" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1073(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1309(td) -msgid "error_suppression_limit" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1075(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1311(td) -msgid "Error count to consider a node error limited" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1080(caption) -msgid "account-server.conf Auditor Options in the [account-auditor] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1089(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1132(td) -msgid "account-auditor" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1108(td) -msgid "accounts_per_second" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1110(td) -msgid "Maximum accounts audited per second. Should be tuned according to individual system specs. 0 is unlimited." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1117(caption) -msgid "account-server.conf Reaper Options in the [account-reaper] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1125(td) -msgid "delay_reaping" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1127(td) -msgid "Number of seconds to delay reaper from deleting account info for deleted accounts. 2592000 = 30 days, for example" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1147(td) -msgid "25" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1169(title) -msgid "Proxy Server Configuration" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1170(para) -msgid "An example Proxy Server configuration can be found at etc/proxy-server.conf-sample in the source code repository." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1174(caption) -msgid "proxy-server.conf Default Options in the [DEFAULT] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1188(td) -msgid "80" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1212(td) -msgid "cert_file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1214(td) -msgid "Path to the ssl .crt" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1217(td) -msgid "key_file" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1219(td) -msgid "Path to the ssl .key" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1229(caption) -msgid "proxy-server.conf Server Options in the [proxy-server] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1240(code) -msgid "egg:swift#proxy" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1239(td) -msgid "Entry point for paste.deploy for the proxy server. For most cases, this should be ." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1244(td) -msgid "proxy-server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1255(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1349(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1413(td) -msgid "Log level" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1263(td) -msgid "recheck_account_existence" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1265(td) -msgid "Cache timeout in seconds to send memcached for account existence" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1268(td) -msgid "recheck_container_existence" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1270(td) -msgid "Cache timeout in seconds to send memcached for container existence" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1273(td) -msgid "object_chunk_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1275(td) -msgid "Chunk size to read from object servers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1278(td) -msgid "client_chunk_size" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1280(td) -msgid "Chunk size to read from clients" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1283(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1421(td) -msgid "memcache_servers" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1284(td) ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1422(td) -msgid "127.0.0.1:11211" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1285(td) -msgid "Comma separated list of memcached servers ip:port." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1293(td) -msgid "client_timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1295(td) -msgid "Timeout to read one chunk from a client" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1314(td) -msgid "allow_account_management" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1316(td) -msgid "Whether account PUTs and DELETEs are even callable" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1322(caption) -msgid "proxy-server.conf Paste.deploy Options in the [filter:swauth] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1333(code) -msgid "egg:swauth#swauth" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1332(td) -msgid "Entry point for paste.deploy to use for auth, set to: to use the swauth downloaded from https://github.com/gholt/swauth" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1338(td) -msgid "auth-server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1357(td) -msgid "reseller_prefix" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1359(td) -msgid "The naming scope for the auth service. Swift storage accounts and auth tokens will begin with this prefix." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1363(td) -msgid "auth_prefix" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1364(td) -msgid "/auth/" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1366(code) -msgid "v" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1365(td) -msgid "The HTTP request path prefix for the auth service. Swift itself reserves anything beginning with the letter ." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1369(td) -msgid "default_swift_cluster" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1370(td) -msgid "local#http://127.0.0.1:8080/v1" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1371(td) -msgid "The default Swift cluster to place newly created accounts on; only needed if you are using Swauth for authentication." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1375(td) -msgid "token_life" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1377(td) -msgid "The number of seconds a token is valid." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1382(td) -msgid "Request timeout" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1385(td) -msgid "super_admin_key" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1386(td) -msgid "None" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1387(td) -msgid "The key for the .super_admin account." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1393(caption) -msgid "proxy-server.conf Server Options in the [filter:cache] section" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1402(td) -msgid "cache" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml:1423(td) -msgid "Comma separated list of memcached servers ip:port. Note: the value in here will be ignored if it is also specified in /etc/swift/proxy-server.conf" -msgstr "" - -#. When image changes, this message will be marked fuzzy or untranslated for you. -#. It doesn't matter what you translate it to: it's not used at all. -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:146(None) -msgid "@@image: 'figures/cyberduck_swift_connection.png'; md5=dc937c99fd4448174485c22f7cfdaefd" -msgstr "" - -#. When image changes, this message will be marked fuzzy or untranslated for you. -#. It doesn't matter what you translate it to: it's not used at all. -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:176(None) -msgid "@@image: 'figures/cyberduck_swift_uploads.png'; md5=693641aacfa7ccc1514cac5fb5c8f315" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:7(title) -msgid "OpenStack Object Storage Tutorials" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:8(para) -msgid "We want people to use OpenStack for practical problem solving, and the increasing size and density of web content makes for a great use-case for object storage. These tutorials show you how to use your OpenStack Object Storage installation for practical purposes, and it assumes Object Storage is already installed." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:14(title) -msgid "Storing Large Photos or Videos on the Cloud" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:16(para) -msgid "In this OpenStack tutorial, we’ll walk through using an Object Storage installation to back up all your photos or videos. As the sensors on consumer-grade and pro-sumer grade cameras generate more and more megapixels, we all need a place to back our files to and know they are safe." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:21(para) -msgid "We'll go through this tutorial in parts:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:24(para) -msgid "Setting up secure access to Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:25(para) -msgid "Configuring Cyberduck for connecting to OpenStack Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:26(para) -msgid "Copying files to the cloud." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:29(title) -msgid "Part I: Setting Up Secure Access" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:30(para) -msgid "In this part, we'll get the proxy server running with SSL on the Object Storage installation. It's a requirement for using Cyberduck as a client interface to Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:33(para) -msgid "You will need a key and certificate to do this, which we can create as a self-signed for the tutorial since we can do the extra steps to have Cyberduck accept it. Creating a self-signed cert can usually be done with these commands on the proxy server:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:40(para) -msgid "Ensure these generated files are in /etc/swift/cert.crt and /etc/swift/cert.key." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:41(para) -msgid "You also should configure your iptables to enable https traffic. Here's an example setup that works." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:58(para) -msgid "If you don't have access to the Object Storage installation to configure these settings, ask your service provider to set up secure access for you." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:59(para) -msgid "Then, edit your proxy-server.conf file to include the following in the [DEFAULT] sections." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:67(para) -msgid "Also, make sure you use https: for all references to the URL for the server in the .conf files as needed." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:69(para) -msgid "Verify that you can connect using the Public URL to Object Storage by using the \"swift\" tool:" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:75(para) -msgid "Okay, you've created the access that Cyberduck expects for your Object Storage installation. Let's start configuring the Cyberduck side of things." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:81(title) -msgid "Part II: Configuring Cyberduck" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:83(para) -msgid "See the Cyberduck website for further details." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:88(para) -msgid "After installing Cyberduck you'll need to change the path/context used for the authentication URL. The default value shipped with Cyberduck is incorrect." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:93(para) -msgid "On OS X open a Terminal window and execute, " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:97(para) -msgid "On Windows open the preferences file in a text editor. The exact location of this file is described here. If this path doesn't exist you may need to start and stop Cyberduck to have it generate the config file. Once you've opened the file add the setting, " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:115(term) -msgid "Server" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:117(para) -msgid "your proxy server's hostname or IP address" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:121(term) -msgid "Port" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:122(para) -msgid "443" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:125(term) -msgid "Username" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:127(para) -msgid "account name followed by a colon and then the user name, for example test:tester" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:134(term) -msgid "Password" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:136(para) -msgid "password for the account and user name entered above" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:143(title) -msgid "Example Cyberduck Swift Connection" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:107(para) -msgid "To connect to Swift start Cyberduck and click the Open Connection toolbar button or choose File > Open Connection. Select Swift (OpenStack Object Storage) in the dropdown and enter your cluster details. " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:153(title) -msgid "Connecting to a Unsecured Swift Cluster" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:154(para) -msgid "An Unsecured Swift Cluster does not use https connections. Download the Unsecured Swift profile file and double click it to import it into Cyberduck." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:159(para) -msgid "When creating a new connection select Swift (HTTP). Enter your connection details as described above. You'll need to change the port since presumably you won't want to use 443." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:167(title) -msgid "Part III: Creating Containers (Folders) and Uploading Files" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:168(para) -msgid "Now you want to create containers to hold your files. Without containers, Object Storage doesn't know where to put the files. In the Action menu, choose New Folder and name the folder." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:173(title) -msgid "Example Cyberduck Swift Showing Uploads" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:171(para) -msgid "Next you can drag and drop files into the created folder or select File > Upload to select files to upload to the OpenStack Object Storage service. " -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml:179(para) -msgid "Et voila! You can back up terabytes of data if you just have the space and the data. That's a lot of pictures or video, so get snapping and rolling!" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:10(title) -msgid "OpenStack Object Storage Administration Manual" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:18(orgname) -msgid "OpenStack" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:22(year) -msgid "2010" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:23(year) -msgid "2011" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:24(year) -msgid "2012" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:25(year) -msgid "2013" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:26(holder) -msgid "OpenStack Foundation" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:28(releaseinfo) -msgid "trunk" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:29(productname) -msgid "OpenStack Object Storage" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:30(pubdate) ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:43(date) -msgid "2012-12-06" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:33(remark) -msgid "Copyright details are filled in by the template." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:37(para) -msgid "OpenStack™ Object Storage offers open source software for cloud-based object storage for any organization. This manual provides guidance for installing, managing, and understanding the software that runs OpenStack Object Storage." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:47(para) -msgid "Bug fixes and cleanup. Fix bug 1034144" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:48(para) -msgid "Add section about cluster health." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:49(para) -msgid "Add a note about the apt-get install for swift3 from Ubuntu Cloud Archive." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:55(date) -msgid "2012-11-09" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:59(para) -msgid "Folsom release of this document." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:65(date) -msgid "2012-08-21" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:69(para) -msgid "Add note to the [filter:cache] section of the proxy-server.conf file reference indicating that the memcache_servers value is ignored if it is specified in /etc/swift/memcache.conf." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:77(para) -msgid "Update Cyberduck tutorial." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:83(date) -msgid "2012-06-05" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:87(para) -msgid "Fix bug 1009170." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:93(date) -msgid "2012-05-03" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:97(para) -msgid "Begin trunk designation." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:103(date) -msgid "2012-05-02" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:107(para) -msgid "Essex release." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:113(date) -msgid "2012-04-27" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:117(para) -msgid "Adds ring copy example." -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:123(date) -msgid "2012-01-01" -msgstr "" - -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:127(para) -msgid "Formatting updates." -msgstr "" - -#. Put one translator per line, in the form of NAME , YEAR1, YEAR2 -#: ./doc/src/docbkx/openstack-object-storage-admin/bk-objectstorage-adminguide.xml:0(None) -msgid "translator-credits" -msgstr "" - diff --git a/doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml b/doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml deleted file mode 100644 index bea956062a..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/objectstorage-config-reference.xml +++ /dev/null @@ -1,1493 +0,0 @@ - -
    -Server Configuration Reference -Swift uses paste.deploy to manage server configurations. Default configuration -options are set in the [DEFAULT] section, and any options specified there -can be overridden in any of the other sections. -
    - Object Server Configuration - An example Object Server configuration can be found at - etc/object-server.conf-sample in the source code - repository. - The following configuration options are - available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    object-server.conf Default Options in the - [DEFAULT] section
    OptionDefaultDescription
    swift_dir/etc/swiftSwift configuration directory
    devices/srv/nodeParent directory of where devices are - mounted
    mount_checktrueWhether or not check if the devices are - mounted to prevent accidentally writing to the - root device
    bind_ip0.0.0.0IP Address for server to bind to
    bind_port6000Port for server to bind to
    bind_timeout30Seconds to attempt bind before giving up
    workersautoNumber of pre-forked process that will accept - connections. Zero means no fork. The default is - "auto" which will use the number of effective - cpu cores.
    max_clients1024Maximum concurrent requests per worker
    backlog4096Maximum number of allowed pending TCP - connections.
    expiring_objects_container_divisor86400 -
    log_nameswiftLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    userswiftUser to run as
    db_preallocationtruePreallocate disk space for new SQLite - databases to decrease fragmentation
    eventlet_debugfalseTurn on debug logging for eventlet
    disable_fallocatefalseDisable "fast fail" fallocate checks if the - underlying filesystem does not support - it.
    fallocate_reserve0The number of bytes for fallocate to reserve, - whether there is space for the given file - size or not. The default fallocate_reserve - is 0, meaning "no reserve". - Some systems behave badly when they completely run out of space. To - alleviate this problem, you can set fallocate_reserve. When the disk free - space falls at or below this amount, fallocate calls will fail, even - if the underlying OS fallocate call would succeed. For example, a - fallocate_reserve of 10737418240 (10G) would make all fallocate calls - fail, even for zero-byte files, when the disk free space falls under - 10G. -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    object-server.conf Server Options in the - [object-server] section
    OptionDefaultDescription
    useThe paste.deploy entry point for the object - server. For most cases, this should be - egg:swift#object.
    log_nameobject-serverLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_requestsTrueWhether or not to log each request
    userswiftUser to run as
    node_timeout3Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    network_chunk_size65536Size of chunks to read/write over the - network
    disk_chunk_size65536Size of chunks to read/write to disk
    max_upload_time86400Maximum time allowed to upload an object
    slow0If > 0, Minimum time in seconds for a PUT - or DELETE request to complete
    auto_create_account_prefix.Prefix used when automatically creating - accounts
    allowed_headerscontent-disposition, content-encoding, - x-delete-at, x-object-manifest,Comma-separated list of headers that can be - set in metadata of an object
    mb_per_sync512On PUTs, sync data every n MB
    replication_serverIf defined, tells object-server how to handle - replication verbs in requests. When set to True - (or 1), only replication verbs will be accepted. - When set to False, replication verbs will be - rejected. When undefined (the default), server - will accept any verb in request.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    object-server.conf Replicator Options in the - [object-replicator] section
    OptionDefaultDescription
    log_nameobject-replicatorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    daemonizeyesWhether or not to run replication as a - daemon
    run_pause30Time in seconds to wait between replication - passes
    concurrency1Number of replication workers to spawn
    timeout5Timeout value sent to rsync –timeout and - –contimeout options
    http_timeout60Maximum duration for an HTTP request
    lockup_timeout1800Attempts to kill all workers if nothing - replicates for lockup_timeout seconds.
    stats_interval300Interval in seconds between logging - replication statistics
    reclaim_age604800Time elapsed in seconds before an object can - be reclaimed
    recon_cache_path/var/cache/swiftDirectory where stats for a few items will be - stored
    recon_enablenoEnable logging of replication stats for - recon
    ring_check_interval15How often (in seconds) to check the ring
    rsync_io_timeout30Passed to rsync for max duration (seconds) of - an I/O op
    rsync_timeout900Max duration (seconds) of a partition - rsync
    vm_test_modenoIndicates that you are using a VM - environment
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    object-server.conf Updater Options in the - [object-updater] section
    OptionDefaultDescription
    log_nameobject-updaterLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    interval300Minimum time for a pass to take
    concurrency1Number of updater workers to spawn
    node_timeout10Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    slowdown0.01Time in seconds to wait between objects
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    object-server.conf Auditor Options in the - [object-auditor] section
    OptionDefaultDescription
    log_nameobject-auditorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_time3600Frequency of status logs in seconds.
    files_per_second20Maximum files audited per second. Should be - tuned according to individual system specs. 0 - is unlimited.
    bytes_per_second10000000Maximum bytes audited per second. Should be - tuned according to individual system specs. 0 - is unlimited.
    zero_byte_files_per_second50Maximum zero byte files audited per - second.
    - When configured, the StaticWeb WSGI middleware serves container data as - a static web site with index file and error file - resolution and optional file listings. This mode is - normally only active for anonymous requests. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    object-server.conf staticweb Options in the - [filter:staticweb] section
    OptionDefaultDescription
    cache_timeout300Number of seconds to cache container x-container-meta-web-* header values.
    log_facilityLOG_LOCAL0Indicate which facility to use for logging staticweb requests.
    log_levelINFOIndicate which level of logging to use for staticweb requests.
    log_namestaticwebIndicate which level of logging to use for staticweb requests.
    log_headersfIndicate which headers to use for logging staticweb requests.
    access_log_level'INFO'Indicate which level of logging to use for staticweb container access.
    access_log_facilityLOG_LOCAL0Indicate which facility to use for logging access to staticweb containers.
    access_log_namestaticwebIndicate which level of logging to use for staticweb container access.
    -
    -
    - Container Server Configuration - An example Container Server configuration can be found at - etc/container-server.conf-sample in the source code repository. - The following configuration options are available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    container-server.conf Default Options in the [DEFAULT] section
    OptionDefaultDescription
    swift_dir/etc/swiftSwift configuration directory
    devices/srv/nodeParent directory of where devices are mounted
    mount_checktrueWhether or not check if the devices are mounted to prevent accidentally - writing to the root device
    bind_ip0.0.0.0IP Address for server to bind to
    bind_port6001Port for server to bind to
    bind_timeout30Seconds to attempt bind before giving up
    workersautoNumber of pre-forked process that will accept - connections. Zero means no fork. The default is - "auto" which will use the number of effective - cpu cores.
    max_clients1024Maximum concurrent requests per worker
    userswiftUser to run as
    db_preallocationtruepreallocate disk space for new SQLite databases to decrease fragmentation
    eventlet_debugfalseturn on debug logging for eventlet
    disable_fallocatefalseDisable "fast fail" fallocate checks if the underlying filesystem does not support it.
    fallocate_reserve0The number of bytes for fallocate to reserve, - whether there is space for the given file - size or not. The default fallocate_reserve - is 0, meaning "no reserve". - Some systems behave badly when they completely run out of space. To - alleviate this problem, you can set fallocate_reserve. When the disk free - space falls at or below this amount, fallocate calls will fail, even - if the underlying OS fallocate call would succeed. For example, a - fallocate_reserve of 10737418240 (10G) would make all fallocate calls - fail, even for zero-byte files, when the disk free space falls under - 10G. -
    log_nameswiftLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    auto_create_account_prefix.Prefix used when automatically creating - accounts
    backlog4096Maximum number of allowed pending TCP connections.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    container-server.conf Server Options in the [container-server] section
    OptionDefaultDescription
    useThe paste.deploy entry point for the - container server. For most cases, this should - be egg:swift#container.
    log_namecontainer-serverLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_requeststrueWhether or not to log each request
    allow_versionsfalseWhether to allow versions of - containers
    node_timeout10Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    replication_serverIf defined, tells object-server how to handle - replication verbs in requests. When set to True - (or 1), only replication verbs will be accepted. - When set to False, replication verbs will be - rejected. When undefined (the default), server - will accept any verb in request.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    container-server.conf Replicator Options in the [container-replicator] section
    OptionDefaultDescription
    log_namecontainer-replicatorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    per_diff1000Limit number of items to get per diff
    concurrency8Number of replication workers to spawn
    run_pause30Time in seconds to wait between replication passes
    node_timeout10Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    reclaim_age604800Time elapsed in seconds before a container can be reclaimed
    interval30Minimum time for a pass to take (s)
    max_diffs100Caps how long the replicator spends trying to sync a database per pass
    vm_test_modenoIndicates that you are using a VM environment
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    container-server.conf Updater Options in the [container-updater] section
    OptionDefaultDescription
    log_namecontainer-updaterLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    interval300Minimum time for a pass to take
    concurrency4Number of updater workers to spawn
    node_timeout3Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    slowdown0.01Time in seconds to wait between containers
    account_suppression_time60Seconds to suppress updating an account that has generated an error -(timeout, not yet found, etc.)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    container-server.conf Auditor Options in the [container-auditor] section
    OptionDefaultDescription
    log_namecontainer-auditorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    interval1800Minimum time for a pass to take
    containers_per_second200Maximum containers audited per second. - Should be tuned according to individual - system specs. 0 is unlimited.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    container-server.conf Sync Options in the [container-sync] section
    OptionDefaultDescription
    log_namecontainer-syncLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    container_time60Maximum amount of time to spend syncing each container
    sync_proxyIf you need to use an HTTP Proxy, set it here (eg http://127.0.0.1:8888); defaults to no proxy.
    -
    -
    - Account Server Configuration - An example Account Server configuration can be found at - etc/account-server.conf-sample in the source code repository. - The following configuration options are available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    account-server.conf Default Options in the [DEFAULT] section
    OptionDefaultDescription
    swift_dir/etc/swiftSwift configuration directory
    devices/srv/nodeParent directory or where devices are mounted
    mount_checktrueWhether or not check if the devices are mounted to prevent accidentally - writing to the root device
    bind_ip0.0.0.0IP Address for server to bind to
    bind_port6002Port for server to bind to
    bind_timeout30Seconds to attempt bind before giving up
    workersautoNumber of pre-forked process that will accept - connections. Zero means no fork. The default is - "auto" which will use the number of effective - cpu cores.
    max_clients1024Maximum concurrent requests per worker
    userswiftUser to run as
    backlog4096Maximum number of allowed pending TCP connections.
    db_preallocationtruepreallocate disk space for new SQLite databases to decrease fragmentation
    eventlet_debugfalseturn on debug logging for eventlet
    disable_fallocatefalseDisable "fast fail" fallocate checks if the underlying filesystem does not support it.
    fallocate_reserve0The number of bytes for fallocate to reserve, - whether there is space for the given file - size or not. The default fallocate_reserve - is 0, meaning "no reserve". - Some systems behave badly when they completely run out of space. To - alleviate this problem, you can set fallocate_reserve. When the disk free - space falls at or below this amount, fallocate calls will fail, even - if the underlying OS fallocate call would succeed. For example, a - fallocate_reserve of 10737418240 (10G) would make all fallocate calls - fail, even for zero-byte files, when the disk free space falls under - 10G. -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    account-server.conf Server Options in the [account-server] section
    OptionDefaultDescription
    useEntry point for paste.deploy for the account server. For most cases, - this should be egg:swift#account.
    log_nameaccount-serverLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_requeststrueWhether or not to log each request
    auto_create_account_prefix.prefix used when automatically creating accounts
    replication_serverIf defined, tells object-server how to handle - replication verbs in requests. When set to True - (or 1), only replication verbs will be accepted. - When set to False, replication verbs will be - rejected. When undefined (the default), server - will accept any verb in request.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    account-server.conf Replicator Options in the [account-replicator] section
    OptionDefaultDescription
    log_nameaccount-replicatorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    per_diff1000Limit number of items to get per diff
    max_diffs100Caps how long the replicator spends trying to sync a database per pass
    concurrency8Number of replication workers to spawn
    run_pause30Time in seconds to wait between replication passes
    node_timeout10Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    reclaim_age604800Time elapsed in seconds before an account can be reclaimed
    vm_test_modenoIndicates that you are using a VM environment
    interval30Minimum time for a pass to take
    error_suppression_interval60Time in seconds that must elapse since the last error for a node to be - considered no longer error limited
    error_suppression_limit10Error count to consider a node error limited
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    account-server.conf Auditor Options in the [account-auditor] section
    OptionDefaultDescription
    log_nameaccount-auditorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    interval1800Minimum time for a pass to take
    accounts_per_second200Maximum accounts audited per second. - Should be tuned according to individual - system specs. 0 is unlimited.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    account-server.conf Reaper Options in the [account-reaper] section
    OptionDefaultDescription
    delay_reaping0Number of seconds to delay reaper from deleting account info for deleted accounts. 2592000 = 30 - days, for example
    log_nameaccount-auditorLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    concurrency25Number of replication workers to spawn
    interval3600Minimum time for a pass to take
    node_timeout10Request timeout to external services
    conn_timeout0.5Connection timeout to external services
    -
    -
    - Proxy Server Configuration - An example Proxy Server configuration can be found at etc/proxy-server.conf-sample - in the source code repository. - The following configuration options are available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    proxy-server.conf Default Options in the [DEFAULT] section
    OptionDefaultDescription
    bind_ip0.0.0.0IP Address for server to bind to
    bind_port80Port for server to bind to
    bind_timeout30Seconds to attempt bind before giving up
    swift_dir/etc/swiftSwift configuration directory
    workersautoNumber of pre-forked process that will accept - connections. Zero means no fork. The default is - "auto" which will use the number of effective - cpu cores.
    max_clients1024Maximum concurrent requests per worker
    userswiftUser to run as
    cert_filePath to the ssl .crt
    key_filePath to the ssl .key
    eventlet_debugfalseturn on debug logging for eventlet
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    proxy-server.conf Server Options in the [proxy-server] section
    OptionDefaultDescription
    useEntry point for paste.deploy for the proxy server. For most cases, this - should be egg:swift#proxy.
    log_nameproxy-serverLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLog level
    log_headersTrueIf True, log headers in each request
    recheck_account_existence60Cache timeout in seconds to send memcached for account existence
    recheck_container_existence60Cache timeout in seconds to send memcached for container existence
    object_chunk_size65536Chunk size to read from object servers
    client_chunk_size65536Chunk size to read from clients
    memcache_servers127.0.0.1:11211Comma separated list of memcached servers ip:port.
    node_timeout10Request timeout to external services
    client_timeout60Timeout to read one chunk from a client
    conn_timeout0.5Connection timeout to external services
    error_suppression_interval60Time in seconds that must elapse since the last error for a node to be - considered no longer error limited
    error_suppression_limit10Error count to consider a node error limited
    allow_account_managementfalseWhether account PUTs and DELETEs are even callable
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    proxy-server.conf Paste.deploy Options in the [filter:swauth] section
    OptionDefaultDescription
    useEntry point for paste.deploy to use for auth, set to: - egg:swauth#swauth to use the swauth downloaded from - https://github.com/gholt/swauth
    log_nameauth-serverLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLog level
    log_headersTrueIf True, log headers in each request
    reseller_prefixAUTHThe naming scope for the auth service. Swift storage accounts and auth - tokens will begin with this prefix.
    auth_prefix/auth/The HTTP request path prefix for the auth service. Swift itself reserves - anything beginning with the letter v.
    default_swift_clusterlocal#http://127.0.0.1:8080/v1The default Swift cluster to place newly created accounts on; only - needed if you are using Swauth for authentication.
    token_life86400The number of seconds a token is valid.
    node_timeout10Request timeout
    super_admin_keyNoneThe key for the .super_admin account.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    proxy-server.conf Server Options in the [filter:cache] section
    OptionDefaultDescription
    log_namecacheLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLog level
    log_headersFalseIf True, log headers in each request
    memcache_servers127.0.0.1:11211Comma separated list of memcached servers ip:port. Note: the value - in here will be ignored if it is also specified in - /etc/swift/proxy-server.conf
    - -
    -
    diff --git a/doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml b/doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml deleted file mode 100644 index 0ba56fb78b..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/objectstorageadmin.xml +++ /dev/null @@ -1,2660 +0,0 @@ - - - System Administration for OpenStack Object Storage - By understanding the concepts inherent to the Object Storage - system you can better monitor and administer your storage - solution. - -
    - - Understanding How Object Storage Works - This section offers a brief overview of each concept in - administering Object Storage. - - The Ring - - A ring represents a mapping between the names of - entities stored on disk and their physical location. - There are separate rings for accounts, containers, and - objects. When other components need to perform any - operation on an object, container, or account, they - need to interact with the appropriate ring to - determine its location in the cluster. - The Ring maintains this mapping using zones, - devices, partitions, and replicas. Each partition in - the ring is replicated, by default, 3 times across the - cluster, and the locations for a partition are stored - in the mapping maintained by the ring. The ring is - also responsible for determining which devices are - used for hand off in failure scenarios. - - Data can be isolated with the concept of zones in - the ring. Each replica of a partition is guaranteed to - reside in a different zone. A zone could represent a - drive, a server, a cabinet, a switch, or even a data - center. - - The partitions of the ring are equally divided among - all the devices in the OpenStack Object Storage - installation. When partitions need to be moved around - (for example if a device is added to the cluster), the - ring ensures that a minimum number of partitions are - moved at a time, and only one replica of a partition - is moved at a time. - - Weights can be used to balance the distribution of - partitions on drives across the cluster. This can be - useful, for example, when different sized drives are - used in a cluster. - - The ring is used by the Proxy server and several - background processes (like replication). - - - Proxy Server - The Proxy Server is responsible for tying together - the rest of the OpenStack Object Storage architecture. - For each request, it will look up the location of the - account, container, or object in the ring (see below) - and route the request accordingly. The public API is - also exposed through the Proxy Server. - A large number of failures are also handled in the - Proxy Server. For example, if a server is unavailable - for an object PUT, it will ask the ring for a hand-off - server and route there instead. - When objects are streamed to or from an object - server, they are streamed directly through the proxy - server to or from the user – the proxy server does not - spool them. - You can use a proxy server with account management - enabled by configuring it in the proxy server - configuration file. - - - - Object Server - - The Object Server is a very simple blob storage - server that can store, retrieve and delete objects - stored on local devices. Objects are stored as binary - files on the filesystem with metadata stored in the - file’s extended attributes (xattrs). This requires - that the underlying filesystem choice for object - servers support xattrs on files. Some filesystems, - like ext3, have xattrs turned off by default. - - Each object is stored using a path derived from the - object name’s hash and the operation’s timestamp. Last - write always wins, and ensures that the latest object - version will be served. A deletion is also treated as - a version of the file (a 0 byte file ending with - “.ts”, which stands for tombstone). This ensures that - deleted files are replicated correctly and older - versions don’t magically reappear due to failure - scenarios. - - - - Container Server - - The Container Server’s primary job is to handle - listings of objects. It does not’t know where those - objects are, just what objects are in a specific - container. The listings are stored as sqlite database - files, and replicated across the cluster similar to - how objects are. Statistics are also tracked that - include the total number of objects, and total storage - usage for that container. - - - Account Server - The Account Server is very similar to the Container - Server, excepting that it is responsible for listings - of containers rather than objects. - - - Replication - - Replication is designed to keep the system in a - consistent state in the face of temporary error - conditions like network outages or drive failures. - The replication processes compare local data with - each remote copy to ensure they all contain the latest - version. Object replication uses a hash list to - quickly compare subsections of each partition, and - container and account replication use a combination of - hashes and shared high water marks. - Replication updates are push based. For object - replication, updating is just a matter of rsyncing - files to the peer. Account and container replication - push missing records over HTTP or rsync whole database - files. - The replicator also ensures that data is removed - from the system. When an item (object, container, or - account) is deleted, a tombstone is set as the latest - version of the item. The replicator will see the - tombstone and ensure that the item is removed from the - entire system. - To separate the cluster-internal replication traffic - from client traffic, separate replication servers can - be used. These replication servers are based on the - standard storage servers, but they listen on the - replication IP and only respond to REPLICATE requests. - Storage servers can serve REPLICATE requests, so an - operator can transition to using a separate replication - network with no cluster downtime. - Replication IP and port information is stored in the - ring on a per-node basis. These parameters will be used - if they are present, but they are not required. If this - information does not exist or is empty for a particular - node, the node's standard IP and port will be used for - replication. - - - Updaters - - There are times when container or account data can - not be immediately updated. This usually occurs during - failure scenarios or periods of high load. If an - update fails, the update is queued locally on the file - system, and the updater will process the failed - updates. This is where an eventual consistency window - will most likely come in to play. For example, suppose - a container server is under load and a new object is - put in to the system. The object will be immediately - available for reads as soon as the proxy server - responds to the client with success. However, the - container server did not update the object listing, - and so the update would be queued for a later update. - Container listings, therefore, may not immediately - contain the object. - In practice, the consistency window is only as large - as the frequency at which the updater runs and may not - even be noticed as the proxy server will route listing - requests to the first container server which responds. - The server under load may not be the one that serves - subsequent listing requests – one of the other two - replicas may handle the listing. - - - Auditors - - Auditors crawl the local server checking the - integrity of the objects, containers, and accounts. If - corruption is found (in the case of bit rot, for - example), the file is quarantined, and replication - will replace the bad file from another replica. If - other errors are found they are logged (for example, - an object’s listing can’t be found on any container - server it should be). - -
    - - - -
    - Object Layout on Storage - Swift uses the underlying filesystem to store the data - on disk. An administrator can use normal filesystem tools - to find and inspect this data. Swift uses the following - convention for storing objects: - - /path_to_mount_points/device/objects/partition/hash_suffix/hash/ - Accounts and containers are stored similarly, with the - "objects" part of the path replaced with "accounts" or - "containers". - The directory is where all of the data for the object is - stored. Inside the directory, there is normally just one - file (named - <timestamp>.data). - The object's data is stored in the file, and the object's - metadata is stored in the extended attributes (xattrs) of - the file. - If a user deletes the object, the - .data file is deleted and a - <timestamp>.ts - ("ts" for "tombstone") file is created as a zero-byte - file. This is a delete marker that will be eventually - reaped, but it exists to ensure that the delete properly - propagates to all replicas in the cluster. - Swift uses this scheme of timestamps in the file name to - implement conflict resolution. Each piece of data is - assigned a timestamp by the proxy server when the request - comes to the cluster, and that timestamp is what's used to - name the file on disk on the object (or account or - container) server. For the common case, there will be a - single file in the directory. If Swift receives multiple, - concurrent requests to write to the same object, it can - happen that multiple .data files are - written to this directory. Swift uses "last-write-wins" to - resolve such conflicts, choosing the most recent file by - timestamp. - -
    - -
    - Configuring and Tuning OpenStack Object Storage - This section walks through deployment options and - considerations. - - You have multiple deployment options to choose from. The - swift services run completely autonomously, which provides - for a lot of flexibility when designing the hardware - deployment for swift. The 4 main services are: - - - - Proxy Services - - - Object Services - - - Container Services - - - Account Services - - - - The Proxy Services are more CPU and network I/O - intensive. If you are using 10g networking to the proxy, - or are terminating SSL traffic at the proxy, greater CPU - power will be required. - The Object, Container, and Account Services (Storage - Services) are more disk and network I/O intensive. - The easiest deployment is to install all services on - each server. There is nothing wrong with doing this, as it - scales each service out horizontally. - At Rackspace, we put the Proxy Services on their own - servers and all of the Storage Services on the same - server. This allows us to send 10g networking to the proxy - and 1g to the storage servers, and keep load balancing to - the proxies more manageable. Storage Services scale out - horizontally as storage servers are added, and we can - scale overall API throughput by adding more - Proxies. - If you need more throughput to either Account or - Container Services, they may each be deployed to their own - servers. For example you might use faster (but more - expensive) SAS or even SSD drives to get faster disk I/O - to the databases. - Load balancing and network design is left as an exercise - to the reader, but this is a very important part of the - cluster, so time should be spent designing the network for - a Swift cluster. -
    -
    - - Preparing the Ring - - Note - "Partition" in this section refers to the logical - partitions of the swift ring - not physical partitions - on Storage node drives. You should setup your Storage - Node disk partitions with one physical partition per - disk, as per the installation instructions . - - The first step is to determine the number of partitions - that will be in the ring. We recommend that there be a - minimum of 100 partitions per drive to insure even - distribution across the drives. A good starting point - might be to figure out the maximum number of drives the - cluster will contain, and then multiply by 100, and then - round up to the nearest power of two. - For example, imagine we are building a cluster that will - have no more than 5,000 drives. That would mean that we - would have a total number of 500,000 partitions, which is - pretty close to 2^19, rounded up. - It is also a good idea to keep the number of partitions - small (relatively). The more partitions there are, the - more work that has to be done by the replicators and other - backend jobs and the more memory the rings consume in - process. The goal is to find a good balance between small - rings and maximum cluster size. - The next step is to determine the number of replicas to - store of the data. Currently it is recommended to use 3 - (as this is the only value that has been tested). The - higher the number, the more storage that is used but the - less likely you are to lose data. - - It is also important to determine how many zones the - cluster should have. It is recommended to start with a - minimum of 5 zones. You can start with fewer, but our - testing has shown that having at least five zones is - optimal when failures occur. We also recommend trying to - configure the zones at as high a level as possible to - create as much isolation as possible. Some example things - to take into consideration can include physical location, - power availability, and network connectivity. For example, - in a small cluster you might decide to split the zones up - by cabinet, with each cabinet having its own power and - network connectivity. The zone concept is very abstract, - so feel free to use it in whatever way best isolates your - data from failure. Zones are referenced by number, - beginning with 1. - You can now start building the ring with: - swift-ring-builder <builder_file> create <part_power> <replicas> <min_part_hours> - - This will start the ring build process creating the - <builder_file> with 2^<part_power> partitions. - <min_part_hours> is the time in hours before a - specific partition can be moved in succession (24 is a - good value for this). - - Devices can be added to the ring with: - swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta> <weight> - - - This will add a device to the ring where - <builder_file> is the name of the builder file that - was created previously, <zone> is the number of the - zone this device is in, <ip> is the ip address of - the server the device is in, <port> is the port - number that the server is running on, <device_name> - is the name of the device on the server (for example: - sdb1), <meta> is a string of metadata for the device - (optional), and <weight> is a float weight that - determines how many partitions are put on the device - relative to the rest of the devices in the cluster (a good - starting point is 100.0 x TB on the drive). Add each - device that will be initially in the cluster. - - Once all of the devices are added to the ring, - run: - swift-ring-builder <builder_file> rebalance - - This will distribute the partitions across the drives in - the ring. It is important whenever making changes to the - ring to make all the changes required before running - rebalance. This will ensure that the ring stays as - balanced as possible, and as few partitions are moved as - possible. - The above process should be done to make a ring for each - storage service (Account, Container and Object). The - builder files will be needed in future changes to the - ring, so it is very important that these be kept and - backed up. The resulting .tar.gz ring file should be - pushed to all of the servers in the cluster. For more - information about building rings, running - swift-ring-builder with no options will display help text - with available commands and options. - -
    -
    - Considerations and Tuning - Fine-tuning your deployment and installation may take - some time and effort. Here are some considerations for - improving performance of an OpenStack Object Storage - installation. -
    - Memcached Considerations - - Several of the Services rely on Memcached for - caching certain types of lookups, such as auth tokens, - and container/account existence. Swift does not do any - caching of actual object data. Memcached should be - able to run on any servers that have available RAM and - CPU. At Rackspace, we run Memcached on the proxy - servers. The memcache_servers config - option in the proxy-server.conf should - contain all memcached servers. -
    -
    - System Time - Time may be relative but it is relatively important - for Swift! Swift uses timestamps to determine which is - the most recent version of an object. It is very - important for the system time on each server in the - cluster to by synced as closely as possible (more so - for the proxy server, but in general it is a good idea - for all the servers). At Rackspace, we use NTP with a - local NTP server to ensure that the system times are - as close as possible. This should also be monitored to - ensure that the times do not vary too much. -
    -
    - - General Service Tuning - Most services support either a worker or concurrency - value in the settings. This allows the services to - make effective use of the cores available. A good - starting point to set the concurrency level for the - proxy and storage services to 2 times the number of - cores available. If more than one service is sharing a - server, then some experimentation may be needed to - find the best balance. - At Rackspace, our Proxy servers have dual quad core - processors, giving us 8 cores. Our testing has shown - 16 workers to be a pretty good balance when saturating - a 10g network and gives good CPU utilization. - Our Storage servers all run together on the same - servers. These servers have dual quad core processors, - for 8 cores total. We run the Account, Container, and - Object servers with 8 workers each. Most of the - background jobs are run at a concurrency of 1, with - the exception of the replicators which are run at a - concurrency of 2. - The above configuration setting should be taken as - suggestions and testing of configuration settings - should be done to ensure best utilization of CPU, - network connectivity, and disk I/O. -
    -
    - RAID Considerations - We recommend that you do not use RAID with - Swift. - The workload for Swift is very write-heavy, with - small random IO accesses. This type of workload - performs very poorly for most parity RAID (e.g., RAID - 2-6). Testing done by Rackspace suggests that under - heavy workloads, the overall RAID performance can - degrade to be as slow as a single drive. - Furthermore, a drive failure in a RAID array can - result in very poor performance on the node until the - RAID rebuilds, which can take a long time. Testing at - Rackspace, using nodes with 24 2T drives, revealed - that a RAID rebuild after a drive failure could take - on the order of two weeks, during which time the node - performance suffered dramatically as the RAID array - functioned in a degraded state. This kind of - significantly degraded performance can potentially - have ripple effects across the rest of the - cluster. -
    -
    - Filesystem Considerations - - Swift is designed to be mostly filesystem - agnostic–the only requirement being that the - filesystem supports extended attributes (xattrs). - After thorough testing with our use cases and hardware - configurations, XFS was the best all-around choice. If - you decide to use a filesystem other than XFS, we - highly recommend thorough testing. - - If you are using XFS, some settings that can - dramatically impact performance. We recommend the - following when creating the XFS partition: - mkfs.xfs -i size=1024 -f - /dev/sda1 - - Setting the inode size is important, as XFS stores - xattr data in the inode. If the metadata is too large - to fit in the inode, a new extent is created, which - can cause quite a performance problem. Upping the - inode size to 1024 bytes provides enough room to write - the default metadata, plus a little headroom. We do - not recommend running Swift on RAID, but if you are - using RAID it is also important to make sure that the - proper sunit and swidth settings get set so that XFS - can make most efficient use of the RAID array. - We also recommend the following example mount - options when using XFS: - mount -t xfs -o - noatime,nodiratime,nobarrier,logbufs=8 /dev/sda1 - /srv/node/sda - - For a standard swift install, all data drives are - mounted directly under /srv/node (as can be seen in - the above example of mounting /dev/sda1 as - /srv/node/sda). If you choose to mount the drives in - another directory, be sure to set the - devices config option in all of the - server configs to point to the correct - directory. - -
    -
    - General System Tuning - Rackspace currently runs Swift on Ubuntu Server - 10.04, and the following changes have been found to be - useful for our use cases. - The following settings should be in - /etc/sysctl.conf: - - -# disable TIME_WAIT.. wait.. -net.ipv4.tcp_tw_recycle=1 -net.ipv4.tcp_tw_reuse=1 - -# disable syn cookies -net.ipv4.tcp_syncookies = 0 - -# double amount of allowed conntrack -net.ipv4.netfilter.ip_conntrack_max = 262144 - - - - To load the updated sysctl settings, run sudo - sysctl -p - A note about changing the TIME_WAIT values. By - default the OS will hold a port open for 60 seconds to - ensure that any remaining packets can be received. - During high usage, and with the number of connections - that are created, it is easy to run out of ports. We - can change this since we are in control of the - network. If you are not in control of the network, or - do not expect high loads, then you may not want to - adjust those values. - Another helpful tuning parameter on slower systems - that helps to ensure enough time is allowed for - service restarts is the -k N (or - --kill-wait N) parameter of - swift-init. This allows you to - change the default (15 second) time (N, in seconds) - that swift waits for processes to die and notably you - can pass --run-dir flag with - swift-init to set where PIDs - will be stored. -
    -
    - Logging Considerations - Swift is set up to log directly to syslog. Every - service can be configured with the - log_facility option to set the syslog - log facility destination. We recommend using syslog-ng - to route the logs to specific log files locally on the - server and also to remote log collecting - servers. - -
    -
    - Working with Rings - The rings determine where data should reside in the - cluster. There is a separate ring for account - databases, container databases, and individual objects - but each ring works in the same way. These rings are - externally managed, in that the server processes - themselves do not modify the rings, they are instead - given new rings modified by other tools. - The ring uses a configurable number of bits from a - path's MD5 hash as a partition index that designates a - device. The number of bits kept from the hash is known - as the partition power, and 2 to the partition power - indicates the partition count. Partitioning the full - MD5 hash ring allows other parts of the cluster to - work in batches of items at once which ends up either - more efficient or at least less complex than working - with each item separately or the entire cluster all at - once. - Another configurable value is the replica count, - which indicates how many of the partition->device - assignments comprise a single ring. For a given - partition number, each replica's device will not be in - the same zone as any other replica's device. Zones can - be used to group devices based on physical locations, - power separations, network separations, or any other - attribute that would lessen multiple replicas being - unavailable at the same time. -
    - Managing Rings with the Ring Builder - The rings are built and managed manually by a - utility called the ring-builder. The ring-builder - assigns partitions to devices and writes an - optimized Python structure to a gzipped, pickled - file on disk for shipping out to the servers. The - server processes just check the modification time - of the file occasionally and reload their - in-memory copies of the ring structure as needed. - Because of how the ring-builder manages changes to - the ring, using a slightly older ring usually just - means one of the three replicas for a subset of - the partitions will be incorrect, which can be - easily worked around. - The ring-builder also keeps its own builder file - with the ring information and additional data - required to build future rings. It is very - important to keep multiple backup copies of these - builder files. One option is to copy the builder - files out to every server while copying the ring - files themselves. Another is to upload the builder - files into the cluster itself. Complete loss of a - builder file will mean creating a new ring from - scratch, nearly all partitions will end up - assigned to different devices, and therefore - nearly all data stored will have to be replicated - to new locations. So, recovery from a builder file - loss is possible, but data will definitely be - unreachable for an extended time. -
    - About the Ring Data Structure - The ring data structure consists of three - top level fields: a list of devices in the - cluster, a list of lists of device ids - indicating partition to device assignments, - and an integer indicating the number of bits - to shift an MD5 hash to calculate the - partition for the hash. -
    - List of Devices in the Ring - - The list of devices is known internally - to the Ring class as devs. Each item in - the list of devices is a dictionary with - the following keys: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    List of Devices and - Keys
    KeyTypeDescription
    idintegerThe index into the list - devices.
    zoneintegerThe zone the devices resides - in.
    weightfloatThe relative weight of the - device in comparison to other - devices. This usually corresponds - directly to the amount of disk - space the device has compared to - other devices. For instance a - device with 1 tera byte of space - might have a weight of 100.0 and - another device with 2 tera bytes of - space might have a weight of 200.0. - This weight can also be used to - bring back into balance a device - that has ended up with more or less - data than desired over time. A good - average weight of 100.0 allows - flexibility in lowering the weight - later if necessary.
    ipstringThe IP address of the server - containing the device.
    portintThe TCP port the listening - server process uses that serves - requests for the device.
    replication_ipstringThe IP address of the server - containing the device in the - replication network.
    replication_portintThe TCP port the listening - replication server process uses - that serves replication requests - for the device.
    devicestringThe on disk name of the device - on the server. For example: - sdb1
    metastringA general-use field for storing - additional information for the - device. This information isn't used - directly by the server processes, - but can be useful in debugging. For - example, the date and time of - installation and hardware - manufacturer could be stored - here.
    - Note: The list of devices may contain - holes, or indexes set to None, for devices - that have been removed from the cluster. - Generally, device ids are not reused. - Also, some devices may be temporarily - disabled by setting their weight to 0.0. - -
    -
    - -
    - Partition Assignment List - This is a list of array(‘I') of - devices ids. The outermost list contains an - array(‘I') for each replica. Each - array(‘I') has a length equal to the - partition count for the ring. Each integer in - the array(‘I') is an index into the - above list of devices. The partition list is - known internally to the Ring class as - _replica2part2dev_id. - - So, to create a list of device dictionaries - assigned to a partition, the Python code would - look like: devices = - [self.devs[part2dev_id[partition]] for - part2dev_id in - self._replica2part2dev_id] - array(‘I') is used for memory - conservation as there may be millions of - partitions. - -
    -
    - Partition Shift Value - The partition shift value is known - internally to the Ring class as _part_shift. - This value used to shift an MD5 hash to - calculate the partition on which the data for - that hash should reside. Only the top four - bytes of the hash is used in this process. For - example, to compute the partition for the path - /account/container/object the Python code - might look like: partition = - unpack_from('>I', - md5('/account/container/object').digest())[0] - >>self._part_shift - -
    -
    -
    - Building the Ring - The initial building of the ring first - calculates the number of partitions that should - ideally be assigned to each device based the - device's weight. For example, if the partition - power of 20 the ring will have 1,048,576 - partitions. If there are 1,000 devices of equal - weight they will each desire 1,048.576 partitions. - The devices are then sorted by the number of - partitions they desire and kept in order - throughout the initialization process. - Then, the ring builder assigns each partition's - replica to the device that desires the most - partitions at that point, with the restriction - that the device is not in the same zone as any - other replica for that partition. Once assigned, - the device's desired partition count is - decremented and moved to its new sorted location - in the list of devices and the process - continues. - When building a new ring based on an old ring, - the desired number of partitions each device wants - is recalculated. Next the partitions to be - reassigned are gathered up. Any removed devices - have all their assigned partitions unassigned and - added to the gathered list. Any devices that have - more partitions than they now desire have random - partitions unassigned from them and added to the - gathered list. Lastly, the gathered partitions are - then reassigned to devices using a similar method - as in the initial assignment described - above. - Whenever a partition has a replica reassigned, - the time of the reassignment is recorded. This is - taken into account when gathering partitions to - reassign so that no partition is moved twice in a - configurable amount of time. This configurable - amount of time is known internally to the - RingBuilder class as min_part_hours. This - restriction is ignored for replicas of partitions - on devices that have been removed, as removing a - device only happens on device failure and there's - no choice but to make a reassignment. - - The above processes don't always perfectly - rebalance a ring due to the random nature of - gathering partitions for reassignment. To help - reach a more balanced ring, the rebalance process - is repeated until near perfect (less 1% off) or - when the balance doesn't improve by at least 1% - (indicating we probably can't get perfect balance - due to wildly unbalanced zones or too many - partitions recently moved). -
    -
    - History of the Ring Design - The ring code went through many iterations - before arriving at what it is now and while it has - been stable for a while now, the algorithm may be - tweaked or perhaps even fundamentally changed if - new ideas emerge. This section will try to - describe the previous ideas attempted and attempt - to explain why they were discarded. - A “live ring” option was considered - where each server could maintain its own copy of - the ring and the servers would use a gossip - protocol to communicate the changes they made. - This was discarded as too complex and error prone - to code correctly in the project time span - available. One bug could easily gossip bad data - out to the entire cluster and be difficult to - recover from. Having an externally managed ring - simplifies the process, allows full validation of - data before it's shipped out to the servers, and - guarantees each server is using a ring from the - same time line. It also means that the servers - themselves aren't spending a lot of resources - maintaining rings. - - A couple of “ring server” options - were considered. One was where all ring lookups - would be done by calling a service on a separate - server or set of servers, but this was discarded - due to the latency involved. Another was much like - the current process but where servers could submit - change requests to the ring server to have a new - ring built and shipped back out to the servers. - This was discarded due to project time constraints - and because ring changes are currently infrequent - enough that manual control was sufficient. - However, lack of quick automatic ring changes did - mean that other parts of the system had to be - coded to handle devices being unavailable for a - period of hours until someone could manually - update the ring. - The current ring process has each replica of a - partition independently assigned to a device. A - version of the ring that used a third of the - memory was tried, where the first replica of a - partition was directly assigned and the other two - were determined by “walking” the ring - until finding additional devices in other zones. - This was discarded as control was lost as to how - many replicas for a given partition moved at once. - Keeping each replica independent allows for moving - only one partition replica within a given time - window (except due to device failures). Using the - additional memory was deemed a good trade off for - moving data around the cluster much less - often. - Another ring design was tried where the - partition to device assignments weren't stored in - a big list in memory but instead each device was - assigned a set of hashes, or anchors. The - partition would be determined from the data item's - hash and the nearest device anchors would - determine where the replicas should be stored. - However, to get reasonable distribution of data - each device had to have a lot of anchors and - walking through those anchors to find replicas - started to add up. In the end, the memory savings - wasn't that great and more processing power was - used, so the idea was discarded. - A completely non-partitioned ring was also tried - but discarded as the partitioning helps many other - parts of the system, especially replication. - Replication can be attempted and retried in a - partition batch with the other replicas rather - than each data item independently attempted and - retried. Hashes of directory structures can be - calculated and compared with other replicas to - reduce directory walking and network - traffic. - - Partitioning and independently assigning - partition replicas also allowed for the best - balanced cluster. The best of the other strategies - tended to give +-10% variance on device balance - with devices of equal weight and +-15% with - devices of varying weights. The current strategy - allows us to get +-3% and +-8% - respectively. - Various hashing algorithms were tried. SHA - offers better security, but the ring doesn't need - to be cryptographically secure and SHA is slower. - Murmur was much faster, but MD5 was built-in and - hash computation is a small percentage of the - overall request handling time. In all, once it was - decided the servers wouldn't be maintaining the - rings themselves anyway and only doing hash - lookups, MD5 was chosen for its general - availability, good distribution, and adequate - speed. -
    -
    -
    - The Account Reaper - The Account Reaper removes data from deleted - accounts in the background. - An account is marked for deletion by a reseller - through the services server's remove_storage_account - XMLRPC call. This simply puts the value DELETED into - the status column of the account_stat table in the - account database (and replicas), indicating the data - for the account should be deleted later. There is no - set retention time and no undelete; it is assumed the - reseller will implement such features and only call - remove_storage_account once it is truly desired the - account's data be removed. - - The account reaper runs on each account server and - scans the server occasionally for account databases - marked for deletion. It will only trigger on accounts - that server is the primary node for, so that multiple - account servers aren't all trying to do the same work - at the same time. Using multiple servers to delete one - account might improve deletion speed, but requires - coordination so they aren't duplicating effort. Speed - really isn't as much of a concern with data deletion - and large accounts aren't deleted that often. - The deletion process for an account itself is pretty - straightforward. For each container in the account, - each object is deleted and then the container is - deleted. Any deletion requests that fail won't stop - the overall process, but will cause the overall - process to fail eventually (for example, if an object - delete times out, the container won't be able to be - deleted later and therefore the account won't be - deleted either). The overall process continues even on - a failure so that it doesn't get hung up reclaiming - cluster space because of one troublesome spot. The - account reaper will keep trying to delete an account - until it eventually becomes empty, at which point the - database reclaim process within the db_replicator will - eventually remove the database files. - If the account reaper fails to clean up an account - after a specified time, the reaper logs a message. - Search your system for such messages. Set the - reap_warn_after configuration - variable to define the frequency of message alerts. - The default is 30 days. -
    - Account Reaper Background and History - At first, a simple approach of deleting an - account through completely external calls was - considered as it required no changes to the - system. All data would simply be deleted in the - same way the actual user would, through the public - REST API. However, the downside was that it would - use proxy resources and log everything when it - didn't really need to. Also, it would likely need - a dedicated server or two, just for issuing the - delete requests. - - A completely bottom-up approach was also - considered, where the object and container servers - would occasionally scan the data they held and - check if the account was deleted, removing the - data if so. The upside was the speed of - reclamation with no impact on the proxies or - logging, but the downside was that nearly 100% of - the scanning would result in no action creating a - lot of I/O load for no reason. - A more container server centric approach was - also considered, where the account server would - mark all the containers for deletion and the - container servers would delete the objects in each - container and then themselves. This has the - benefit of still speedy reclamation for accounts - with a lot of containers, but has the downside of - a pretty big load spike. The process could be - slowed down to alleviate the load spike - possibility, but then the benefit of speedy - reclamation is lost and what's left is just a more - complex process. Also, scanning all the containers - for those marked for deletion when the majority - wouldn't be seemed wasteful. The db_replicator - could do this work while performing its - replication scan, but it would have to spawn and - track deletion processes which seemed needlessly - complex. - In the end, an account server centric approach - seemed best, as described above. - -
    -
    -
    -
    - Replication - Since each replica in OpenStack Object Storage functions - independently, and clients generally require only a simple - majority of nodes responding to consider an operation - successful, transient failures like network partitions can - quickly cause replicas to diverge. These differences are - eventually reconciled by asynchronous, peer-to-peer - replicator processes. The replicator processes traverse - their local filesystems, concurrently performing - operations in a manner that balances load across physical - disks. - Replication uses a push model, with records and files - generally only being copied from local to remote replicas. - This is important because data on the node may not belong - there (as in the case of and ring changes), and a - replicator can't know what data exists elsewhere in the - cluster that it should pull in. It's the duty of any node - that contains data to ensure that data gets to where it - belongs. Replica placement is handled by the ring. - - Every deleted record or file in the system is marked by - a tombstone, so that deletions can be replicated alongside - creations. These tombstones are cleaned up by the - replication process after a period of time referred to as - the consistency window, which is related to replication - duration and how long transient failures can remove a node - from the cluster. Tombstone cleanup must be tied to - replication to reach replica convergence. - If a replicator detects that a remote drive has failed, - it will use the ring's “get_more_nodes” - interface to choose an alternate node to synchronize with. - The replicator can generally maintain desired levels of - replication in the face of hardware failures, though some - replicas may not be in an immediately usable - location. - Replication is an area of active development, and likely - rife with potential improvements to speed and - correctness. - There are two major classes of replicator - the db - replicator, which replicates accounts and containers, and - the object replicator, which replicates object - data. -
    - Database Replication - The first step performed by db replication is a - low-cost hash comparison to find out whether or not - two replicas already match. Under normal operation, - this check is able to verify that most databases in - the system are already synchronized very quickly. If - the hashes differ, the replicator brings the databases - in sync by sharing records added since the last sync - point. - - This sync point is a high water mark noting the last - record at which two databases were known to be in - sync, and is stored in each database as a tuple of the - remote database id and record id. Database ids are - unique amongst all replicas of the database, and - record ids are monotonically increasing integers. - After all new records have been pushed to the remote - database, the entire sync table of the local database - is pushed, so the remote database knows it's now in - sync with everyone the local database has previously - synchronized with. - If a replica is found to be missing entirely, the - whole local database file is transmitted to the peer - using rsync(1) and vested with a new unique id. - In practice, DB replication can process hundreds of - databases per concurrency setting per second (up to - the number of available CPUs or disks) and is bound by - the number of DB transactions that must be - performed. -
    -
    - Object Replication - The initial implementation of object replication - simply performed an rsync to push data from a local - partition to all remote servers it was expected to - exist on. While this performed adequately at small - scale, replication times skyrocketed once directory - structures could no longer be held in RAM. We now use - a modification of this scheme in which a hash of the - contents for each suffix directory is saved to a - per-partition hashes file. The hash for a suffix - directory is invalidated when the contents of that - suffix directory are modified. - The object replication process reads in these hash - files, calculating any invalidated hashes. It then - transmits the hashes to each remote server that should - hold the partition, and only suffix directories with - differing hashes on the remote server are rsynced. - After pushing files to the remote server, the - replication process notifies it to recalculate hashes - for the rsynced suffix directories. - Performance of object replication is generally bound - by the number of uncached directories it has to - traverse, usually as a result of invalidated suffix - directory hashes. Using write volume and partition - counts from our running systems, it was designed so - that around 2% of the hash space on a normal node will - be invalidated per day, which has experimentally given - us acceptable replication speeds. - -
    -
    - -
    - - Managing Large Objects (Greater than 5 GB) - OpenStack Object Storage has a limit on the size of a - single uploaded object; by default this is 5GB. However, - the download size of a single object is virtually - unlimited with the concept of segmentation. Segments of - the larger object are uploaded and a special manifest file - is created that, when downloaded, sends all the segments - concatenated as a single object. This also offers much - greater upload speed with the possibility of parallel - uploads of the segments. -
    - Using swift to Manage Segmented Objects - - The quickest way to try out this feature is use the - included swift OpenStack Object Storage client tool. - You can use the -S option to specify the segment size - to use when splitting a large file. For - example: - # swift upload test_container -S 1073741824 large_file - - This would split the large_file into 1G segments and - begin uploading those segments in parallel. Once all - the segments have been uploaded, swift will then - create the manifest file so the segments can be - downloaded as one. - So now, the following st command would download the - entire large object: - - swift download test_container large_file - - The swift CLI uses a strict convention for its - segmented object support. In the above example it will - upload all the segments into a second container named - test_container_segments. These segments will have - names like - large_file/1290206778.25/21474836480/00000000, - large_file/1290206778.25/21474836480/00000001, - etc. - The main benefit for using a separate container is - that the main container listings will not be polluted - with all the segment names. The reason for using the - segment name format of - <name>/<timestamp>/<size>/<segment> - is so that an upload of a new file with the same name - won't overwrite the contents of the first until the - last moment when the manifest file is updated. - - The swift CLI will manage these segment files for - you, deleting old segments on deletes and overwrites, - etc. You can override this behavior with the - --leave-segments option if desired; this is useful if - you want to have multiple versions of the same large - object available. -
    -
    - Direct API Management of Large Objects - You can also work with the segments and manifests - directly with HTTP requests instead of having swift do - that for you. You can just upload the segments like - you would any other object and the manifest is just a - zero-byte file with an extra X-Object-Manifest - header. - - All the object segments need to be in the same - container, have a common object name prefix, and their - names sort in the order they should be concatenated. - They don't have to be in the same container as the - manifest file will be, which is useful to keep - container listings clean as explained above with - st. - The manifest file is simply a zero-byte file with - the extra - X-Object-Manifest:<container>/<prefix> - header, where <container> is the - container the object segments are in and - <prefix> is the common prefix for all the - segments. - - It is best to upload all the segments first and then - create or update the manifest. In this way, the full - object won't be available for downloading until the - upload is complete. Also, you can upload a new set of - segments to a second location and then update the - manifest to point to this new location. During the - upload of the new segments, the original manifest will - still be available to download the first set of - segments. - Here's an example using curl with tiny 1-byte - segments: - # First, upload the segments - -$ curl -X PUT -H 'X-Auth-Token: <token>' http://<storage_url>/container/myobject/1 --data-binary '1' -$ curl -X PUT -H 'X-Auth-Token: <token>' http://<storage_url>/container/myobject/2 --data-binary '2' -$ curl -X PUT -H 'X-Auth-Token: <token>' http://<storage_url>/container/myobject/3 --data-binary '3' - - # Next, create the manifest file curl -X PUT -H - 'X-Auth-Token: <token>' \ -H 'X-Object-Manifest: - container/myobject/' \ - http://<storage_url>/container/myobject - --data-binary '' # And now we can download the - segments as a single object curl -H 'X-Auth-Token: - <token>' \ - http://<storage_url>/container/myobject - -
    -
    - Additional Notes on Large Objects - - - With a GET or HEAD of a manifest file, the - X-Object-Manifest: - <container>/<prefix> - header will be returned with the concatenated - object so you can tell where it's getting its - segments from. - - - - The response's Content-Length for a GET or - HEAD on the manifest file will be the sum of - all the segments in the - <container>/<prefix> listing, - dynamically. So, uploading additional segments - after the manifest is created will cause the - concatenated object to be that much larger; - there's no need to recreate the manifest - file. - - - - The response's Content-Type for a GET or - HEAD on the manifest will be the same as the - Content-Type set during the PUT request that - created the manifest. You can easily change - the Content-Type by reissuing the PUT. - - - - The response's ETag for a GET or HEAD on the - manifest file will be the MD5 sum of the - concatenated string of ETags for each of the - segments in the - <container>/<prefix> listing, - dynamically. Usually in OpenStack Object - Storage the ETag is the MD5 sum of the - contents of the object, and that holds true - for each segment independently. But, it's not - feasible to generate such an ETag for the - manifest itself, so this method was chosen to - at least offer change detection. - - -
    -
    - Large Object Storage History and Background - Large object support has gone through various - iterations before settling on this - implementation. - The primary factor driving the limitation of object - size in OpenStack Object Storage is maintaining - balance among the partitions of the ring. To maintain - an even dispersion of disk usage throughout the - cluster the obvious storage pattern was to simply - split larger objects into smaller segments, which - could then be glued together during a read. - Before the introduction of large object support some - applications were already splitting their uploads into - segments and re-assembling them on the client side - after retrieving the individual pieces. This design - allowed the client to support backup and archiving of - large data sets, but was also frequently employed to - improve performance or reduce errors due to network - interruption. The major disadvantage of this method is - that knowledge of the original partitioning scheme is - required to properly reassemble the object, which is - not practical for some use cases, such as CDN - origination. - In order to eliminate any barrier to entry for - clients wanting to store objects larger than 5GB, - initially we also prototyped fully transparent support - for large object uploads. A fully transparent - implementation would support a larger max size by - automatically splitting objects into segments during - upload within the proxy without any changes to the - client API. All segments were completely hidden from - the client API. - This solution introduced a number of challenging - failure conditions into the cluster, wouldn't provide - the client with any option to do parallel uploads, and - had no basis for a resume feature. The transparent - implementation was deemed just too complex for the - benefit. - - The current “user manifest” design was - chosen in order to provide a transparent download of - large objects to the client and still provide the - uploading client a clean API to support segmented - uploads. - Alternative “explicit” user manifest - options were discussed which would have required a - predefined format for listing the segments to - “finalize” the segmented upload. While - this may offer some potential advantages, it was - decided that pushing an added burden onto the client - which could potentially limit adoption should be - avoided in favor of a simpler “API” - (essentially just the format of the - ‘X-Object-Manifest' header). - - During development it was noted that this - “implicit” user manifest approach which is - based on the path prefix can be potentially affected - by the eventual consistency window of the container - listings, which could theoretically cause a GET on the - manifest object to return an invalid whole object for - that short term. In reality you're unlikely to - encounter this scenario unless you're running very - high concurrency uploads against a small testing - environment which isn't running the object-updaters or - container-replicators. - Like all of OpenStack Object Storage, Large Object - Support is living feature which will continue to - improve and may change over time. - -
    -
    -
    - - Throttling Resources by Setting Rate Limits - - Rate limiting in OpenStack Object Storage is implemented - as a pluggable middleware that you configure on the proxy - server. Rate limiting is performed on requests that result - in database writes to the account and container sqlite - dbs. It uses memcached and is dependent on the proxy - servers having highly synchronized time. The rate limits - are limited by the accuracy of the proxy server - clocks. -
    - - Configuration for Rate Limiting - All configuration is optional. If no account or - container limits are provided there will be no rate - limiting. Configuration available: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for rate limiting in - proxy-server.conf file
    OptionDefaultDescription
    clock_accuracy1000Represents how accurate the proxy servers' - system clocks are with each other. 1000 - means that all the proxies' clock are - accurate to each other within 1 - millisecond. No rate limit should be - higher than the clock accuracy.
    max_sleep_time_seconds60App will immediately return a 498 response - if the necessary sleep time ever exceeds - the given max_sleep_time_seconds.
    log_sleep_time_seconds0To allow visibility into rate limiting set - this value > 0 and all sleeps greater - than the number will be logged.
    log_nameswiftLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_headersFalseIf True, log headers in each request
    account_ratelimit0If set, will limit all requests to - /account_name and PUTs to - /account_name/container_name. Number is in - requests per second
    account_whitelist‘'Comma separated lists of account names - that will not be rate limited.
    account_blacklist‘'Comma separated lists of account names - that will not be allowed. Returns a 497 - response.
    container_ratelimit_size‘'When set with container_limit_x = r: for - containers of size x, limit requests per - second to r. Will limit GET and HEAD - requests to /account_name/container_name - and PUTs and DELETEs to - /account_name/container_name/object_name
    rate_buffer_seconds5Number of seconds the rate counter can - drop and be allowed to catch up (faster - than the listed rate). A larger number - will result in larger average spikes but - better average accuracy.
    - The container rate limits are linearly interpolated - from the values given. A sample container rate - limiting could be: - container_ratelimit_100 = 100 - container_ratelimit_200 = 50 - container_ratelimit_500 = 20 - This would result in - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Values for Rate Limiting with Sample - Configuration Settings
    Container SizeRate Limit
    0-99No limiting
    100100
    15075
    50020
    100020
    - -
    -
    -
    - - Additional Features - This section aims to detail a number of additional - features in Swift and their configuration. -
    - - Health Check - Health Check provides a simple way to monitor if the - swift proxy server is alive. If the proxy is access - with the path /healthcheck, it will respond with “OK” - in the body, which can be used by monitoring - tools. - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for filter:healthcheck - in proxy-server.conf file
    OptionDefaultDescription
    log_nameswiftLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    -
    - -
    - - Domain Remap - Domain Remap is middleware that translates container - and account parts of a domain to path parameters that - the proxy server understands. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for filter:domain_remap - in proxy-server.conf file
    OptionDefaultDescription
    log_nameswiftLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_headersFalseIf True, log headers in each request
    path_rootv1Root path
    reseller_prefixesAUTHReseller prefix
    storage_domainexample.comDomain to use for remap
    -
    - -
    - - CNAME Lookup - CNAME Lookup is middleware that translates an - unknown domain in the host header to something that - ends with the configured storage_domain by looking up - the given domain's CNAME record in DNS. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for filter:cname_lookup - in proxy-server.conf file
    OptionDefaultDescription
    log_nameswiftLabel used when logging
    log_facilityLOG_LOCAL0Syslog log facility
    log_levelINFOLogging level
    log_headersFalseIf True, log headers in each request
    lookup_depth1As CNAMEs can be recursive, how many - levels to search through.
    storage_domainexample.conf -
    -
    -
    - Temporary URL - Allows the creation of URLs to provide temporary - access to objects. For example, a website may wish to - provide a link to download a large object in Swift, - but the Swift account has no public access. The - website can generate a URL that will provide GET - access for a limited time to the resource. When the - web browser user clicks on the link, the browser will - download the object directly from Swift, obviating the - need for the website to act as a proxy for the - request. If the user were to share the link with all - his friends, or accidentally post it on a forum, etc. - the direct access would be limited to the expiration - time set when the website created the link. To create - such temporary URLs, first an - X-Account-Meta-Temp-URL-Key header must be set on the - Swift account. Then, an HMAC-SHA1 (RFC 2104) signature - is generated using the HTTP method to allow (GET or - PUT), the Unix timestamp the access should be allowed - until, the full path to the object, and the key set on - the account. For example, here is code generating the - signature for a GET for 60 seconds on - /v1/AUTH_account/container/object: - - import hmac - from hashlib import sha1 - from time import time - method = 'GET' - expires = int(time() + 60) - path = '/v1/AUTH_account/container/object' - key = 'mykey' - hmac_body = '%s\n%s\n%s' % (method, expires, path) - sig = hmac.new(key, hmac_body, sha1).hexdigest() - - - Be certain to use the full path, from the /v1/ - onward. Let's say the sig ends up equaling - da39a3ee5e6b4b0d3255bfef95601890afd80709 and expires - ends up 1323479485. Then, for example, the website - could provide a link to: - - https://swift-cluster.example.com/v1/AUTH_account/container/object? - temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& - temp_url_expires=1323479485 - - Any alteration of the resource path or query - arguments would result in 401 Unauthorized. Similarly, - a PUT where GET was the allowed method would 401. HEAD - is allowed if GET or PUT is allowed. Using this in - combination with browser form post translation - middleware could also allow direct-from-browser - uploads to specific locations in Swift. Note that - changing the X-Account-Meta-Temp-URL-Key will - invalidate any previously generated temporary URLs - within 60 seconds (the memcache time for the key). - A script called swift-temp-url distributed with swift source - code eases the temporary URL creation: - - $ bin/swift-temp-url GET 3600 /v1/AUTH_account/container/object mykey - /v1/AUTH_account/container/object? - temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91& - temp_url_expires=1374497657 - - The path returned by the above command is prefixed with swift - storage hostname. - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for filter:tempurl in - proxy-server.conf file
    OptionDefaultDescription
    incoming_allow_headers - -
    incoming_remove_headersx-timestamp -
    outgoing_allow_headersx-object-meta-public-* -
    outgoing_remove_headersx-object-meta-* -
    -
    -
    - - Name Check Filter - Name Check is a filter that disallows any paths that - contain defined forbidden characters or that exceed a - defined length. - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for filter:name_check - in proxy-server.conf file
    OptionDefaultDescription
    forbidden_chars - Characters that are not allowed in a - name
    max_length255Maximum length of a name
    forbidden_regexp"/\./|/\.\./|/\.$|/\.\.$"Substrings to forbid, using regular - expression syntax
    -
    -
    - - Constraints - The swift-constraints section in - swift.conf allows modification - of internal limits within swift. These are advanced - features for tuning the performance of the cluster and - should be altered with caution. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for swift-constraints - in swift.conf
    OptionDefaultDescription
    max_file_size5368709122the 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_meta_name_length128the max number of bytes in the utf8 - encoding of the name portion of a metadata - header.
    max_meta_value_lenth256the max number of bytes in the utf8 - encoding of a metadata value
    max_meta_count90the max number of metadata keys that can - be stored on a single account, container, - or object
    max_meta_overall_size4096the max number of bytes in the utf8 - encoding of the metadata (keys + - values)
    max_object_name_length1024the max number of bytes in the utf8 - encoding of an object name
    container_listing_limit10000the default (and max) number of items - returned for a container listing - request
    max_account_name_length256the max number of bytes in the utf8 - encoding of an account name
    max_container_name_length256the max number of bytes in the utf8 - encoding of a container name
    -
    -
    - - Cluster Health - There is a - swift-dispersion-report tool - for measuring overall cluster health. This is - accomplished by checking if a set of deliberately - distributed containers and objects are currently in - their proper places within the cluster. For instance, - a common deployment has three replicas of each object. - The health of that object can be measured by checking - if each replica is in its proper place. If only 2 of - the 3 is in place the object’s heath can be said to be - at 66.66%, where 100% would be perfect. A single - object’s health, especially an older object, usually - reflects the health of that entire partition the - object is in. If we make enough objects on a distinct - percentage of the partitions in the cluster, we can - get a pretty valid estimate of the overall cluster - health. In practice, about 1% partition coverage seems - to balance well between accuracy and the amount of - time it takes to gather results. The first thing that - needs to be done to provide this health value is - create a new account solely for this usage. Next, we - need to place the containers and objects throughout - the system so that they are on distinct partitions. - The swift-dispersion-populate tool does this by making - up random container and object names until they fall - on distinct partitions. Last, and repeatedly for the - life of the cluster, we need to run the - swift-dispersion-report tool to check the health of - each of these containers and objects. These tools need - direct access to the entire cluster and to the ring - files (installing them on a proxy server will probably - do). Both swift-dispersion-populate and - swift-dispersion-report use the same configuration - file, /etc/swift/dispersion.conf. - Example dispersion.conf file: - -[dispersion] -auth_url = http://localhost:8080/auth/v1.0 -auth_user = test:tester -auth_key = testing - - There are also options for the conf file for - specifying the dispersion coverage (defaults to 1%), - retries, concurrency, etc. though usually the defaults - are fine. Once the configuration is in place, run - swift-dispersion-populate to populate the containers - and objects throughout the cluster. Now that those - containers and objects are in place, you can run - swift-dispersion-report to get a dispersion report, or - the overall health of the cluster. Here is an example - of a cluster in perfect health: - -$ swift-dispersion-report -Queried 2621 containers for dispersion reporting, 19s, 0 retries -100.00% of container copies found (7863 of 7863) -Sample represents 1.00% of the container partition space - -Queried 2619 objects for dispersion reporting, 7s, 0 retries -100.00% of object copies found (7857 of 7857) -Sample represents 1.00% of the object partition space - - Now, deliberately double the weight of a device in the - object ring (with replication turned off) and rerun - the dispersion report to show what impact that has: - -$ swift-ring-builder object.builder set_weight d0 200 -$ swift-ring-builder object.builder rebalance -... -$ swift-dispersion-report -Queried 2621 containers for dispersion reporting, 8s, 0 retries -100.00% of container copies found (7863 of 7863) -Sample represents 1.00% of the container partition space - -Queried 2619 objects for dispersion reporting, 7s, 0 retries -There were 1763 partitions missing one copy. -77.56% of object copies found (6094 of 7857) -Sample represents 1.00% of the object partition space - - You can see the health of the objects in the cluster - has gone down significantly. Of course, this test - environment has just four devices, in a production - environment with many devices the impact of one device - change is much less. Next, run the replicators to get - everything put back into place and then rerun the - dispersion report: - -... start object replicators and monitor logs until they're caught up ... -$ swift-dispersion-report -Queried 2621 containers for dispersion reporting, 17s, 0 retries -100.00% of container copies found (7863 of 7863) -Sample represents 1.00% of the container partition space - -Queried 2619 objects for dispersion reporting, 7s, 0 retries -100.00% of object copies found (7857 of 7857) -Sample represents 1.00% of the object partition space - - Alternatively, the dispersion report can also be - output in json format. This allows it to be more - easily consumed by third party utilities: - -$ swift-dispersion-report -j -{"object": {"retries:": 0, "missing_two": 0, "copies_found": 7863, "missing_one": 0, -"copies_expected": 7863, "pct_found": 100.0, "overlapping": 0, "missing_all": 0}, "container": -{"retries:": 0, "missing_two": 0, "copies_found": 12534, "missing_one": 0, "copies_expected": -12534, "pct_found": 100.0, "overlapping": 15, "missing_all": 0}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration options for dispersion in - proxy-server.conf file
    OptionDefaultDescription
    auth_version1.0Swift authentication API version
    dispersion_coverage1.0 -
    dump_json'no' -
    retries3 -
    auth_url - -
    auth_user - -
    auth_key - -
    swift_dir/etc/swift -
    -
    - -
    - Static Large Object (SLO) support - This feature is very similar to Dynamic Large Object - (DLO) support in that it allows the user to upload - many objects concurrently and afterwards download them - as a single object. It is different in that it does - not rely on eventually consistent container listings - to do so. Instead, a user defined manifest of the - object segments is used. -
    - Uploading the Manifest - After the user has uploaded the objects to be - concatenated a manifest is uploaded. The request - must be a PUT with the query parameter:: - ?multipart-manifest=put - The body of this request will be an ordered list - of files in json data format. The data to be - supplied for each segment is: - - path: the path to the segment (not - including account) - /container/object_name - - - etag: the etag given back when the - segment was PUT - - - size_bytes: the size of the segment - in bytes - - The format of the list will be: - - json: - [{"path": "/cont/object", - "etag": "etagoftheobjectsegment", - "size_bytes": 1048576}, ...] - - The number of object segments is limited to a - configurable amount, default 1000. Each segment, - except for the final one, must be at least 1 - megabyte (configurable). On upload, the middleware - will head every segment passed in and verify the - size and etag of each. If any of the objects do - not match (not found, size/etag mismatch, below - minimum size) then the user will receive a 4xx - error response. If everything does match, the user - will receive a 2xx response and the SLO object is - ready for downloading. - Behind the scenes, on success, a json manifest - generated from the user input is sent to object - servers with an extra "X-Static-Large-Object: - True" header and a modified Content-Type. The - parameter: swift_bytes=$total_size will be - appended to the existing Content-Type, where - total_size is the sum of all the included - segments' size_bytes. This extra parameter will be - hidden from the user. - Manifest files can reference objects in separate - containers, which will improve concurrent upload - speed. Objects can be referenced by multiple - manifests. -
    -
    - Retrieving a Large Object - A GET request to the manifest object will return - the concatenation of the objects from the manifest - much like DLO. If any of the segments from the - manifest are not found or their Etag/Content - Length no longer match the connection will drop. - In this case a 409 Conflict will be logged in the - proxy logs and the user will receive incomplete - results. - The headers from this GET or HEAD request will - return the metadata attached to the manifest - object itself with some exceptions: - - Content-Length: the total size of - the SLO (the sum of the sizes of the - segments in the manifest) - - - X-Static-Large-Object: True - - - Etag: the etag of the SLO (generated - the same way as DLO) - - A GET request with the query - parameter:: - ?multipart-manifest=get - Will return the actual manifest file itself. This - is generated json and does not match the data sent - from the original multipart-manifest=put. Use this - call for debugging. - When the manifest object is uploaded you are - more or less guaranteed that every segment in the - manifest exists and matched the specifications. - However, there is nothing that prevents the user - from breaking the SLO download by - deleting/replacing a segment referenced in the - manifest. It is left to the user use caution in - handling the segments. -
    -
    - Deleting a Large Object - - A DELETE request will just delete the manifest - object itself. A DELETE with a query parameter: - ?multipart-manifest=delete - will delete all the segments referenced in the - manifest and then, if successful, the manifest - itself. The failure response will be similar to - the bulk delete middleware. -
    -
    - Modifying a Large Object - PUTs / POSTs will work as expected, PUTs will - just overwrite the manifest object for example. - -
    -
    - Container Listings - In a container listing the size listed for SLO - manifest objects will be the total_size of the - concatenated segments in the manifest. The overall - X-Container-Bytes-Used for the container (and - subsequently for the account) will not reflect - total_size of the manifest but the actual size of - the json data stored. The reason for this somewhat - confusing discrepancy is we want the container - listing to reflect the size of the manifest object - when it is downloaded. We do not, however, want to - count the bytes-used twice (for both the manifest - and the segments it's referring to) in the - container and account metadata which can be used - for stats purposes. -
    -
    -
    - Container Quotas - The container_quotas middleware implements simple - quotas that can be imposed on swift containers by a - user with the ability to set container metadata, most - likely the account administrator. This can be useful - for limiting the scope of containers that are - delegated to non-admin users, exposed to formpost - uploads, or just as a self-imposed sanity - check. - - Any object PUT operations that exceed these quotas - return a 413 response (request entity too large) with - a descriptive body. - - Quotas are subject to several limitations: eventual - consistency, the timeliness of the cached - container_info (60 second ttl by default), and it's - unable to reject chunked transfer uploads that exceed - the quota (though once the quota is exceeded, new - chunked transfers will be refused). - - Quotas are set by adding meta values to the - container, and are validated when set: - - X-Container-Meta-Quota-Bytes: Maximum - size of the container, in bytes. - - - X-Container-Meta-Quota-Count: Maximum - object count of the container. - - - -
    -
    - Account Quotas - The account_quotas middleware aims to block write - requests (PUT, POST) if a given account quota (in bytes) - is exceeded while DELETE requests are still - allowed. - The x-account-meta-quota-bytes metadata entry must - be set to store and enable the quota. Write requests - to this metadata entry are only permitted for resellers. - There isn't any account quota limitation on a reseller - account even if x-account-meta-quota-bytes is set. - Any object PUT operations that exceed the quota - return a 413 response (request entity too large) with - a descriptive body. - The following command uses an admin account that own - the Reseller role to set a quota on the test account: - swift -A http://127.0.0.1:8080/auth/v1.0 -U admin:admin -K admin --os-storage-url=http://127.0.0.1:8080/v1/AUTH_test post -m quota-bytes:10000 - Here is the stat listing of an account where quota has been set: - swift -A http://127.0.0.1:8080/auth/v1.0 -U test:tester -K testing stat - Account: AUTH_test - Containers: 0 - Objects: 0 - Bytes: 0 - Meta Quota-Bytes: 10000 - X-Timestamp: 1374075958.37454 - X-Trans-Id: tx602634cf478546a39b1be-0051e6bc7a - - The command below removes the account quota: - swift -A http://127.0.0.1:8080/auth/v1.0 -U admin:admin -K admin --os-storage-url=http://127.0.0.1:8080/v1/AUTH_test post -m quota-bytes: - -
    -
    - -
    - Bulk Delete - Will delete multiple files from their account with a - single request. Responds to DELETE requests with a header - 'X-Bulk-Delete: true_value'. The body of the DELETE - request will be a newline separated list of files to - delete. The files listed must be URL encoded and in the - form: - - /container_name/obj_name - - - If all files were successfully deleted (or did not - exist) will return an HTTPOk. If any files failed to - delete will return an HTTPBadGateway. In both cases the - response body is a json dictionary specifying in the - number of files successfully deleted, not found, and a - list of the files that failed. -
    - -
    - - Configuring Object Storage with the S3 API - The Swift3 middleware emulates the S3 REST API on top of - Object Storage. - - The following operations are currently supported: - - - - GET Service - - - DELETE Bucket - - - GET Bucket (List Objects) - - - PUT Bucket - - - DELETE Object - - - GET Object - - - HEAD Object - - - PUT Object - - - PUT Object (Copy) - - - To use this middleware, first download the latest - version from its repository to your proxy - server(s). - $ git clone https://github.com/fujita/swift3.git - Optional: To use this middleware with Swift 1.7.0 and - previous versions, you'll need to use the v1.7 tag of the - fujita/swift3 repository. Clone the repo as above and - then: - $ cd swift3; git checkout v1.7 - Then, install it using standard python mechanisms, such - as: - $ sudo python setup.py install - Alternatively, if you have configured the Ubuntu Cloud - Archive, you may use: - $ sudo apt-get install swift-python-s3 - To add this middleware to your configuration, add the - swift3 middleware in front of the auth middleware, and - before any other middleware that look at swift requests - (like rate limiting). - - Ensure that your proxy-server.conf file contains swift3 - in the pipeline and the [filter:swift3] section, as shown - below: - -[pipeline:main] -pipeline = healthcheck cache swift3 swauth proxy-server - -[filter:swift3] -use = egg:swift3#swift3 - - Next, configure the tool that you use to connect to the - S3 API. For S3curl, for example, you'll need to add your - host IP information by adding y our host IP to the - @endpoints array (line 33 in s3curl.pl): - - my @endpoints = ( '1.2.3.4'); - Now you can send commands to the endpoint, such - as: - -$ ./s3curl.pl - 'myacc:myuser' -key mypw -get - -s -v http://1.2.3.4:8080 - - To set up your client, the access key will be the - concatenation of the account and user strings that should - look like test:tester, and the secret access key is the - account password. The host should also point to the Swift - storage node's hostname. It also will have to use the - old-style calling format, and not the hostname-based - container format. Here is an example client setup using - the Python boto library on a locally installed all-in-one - Swift installation. - -connection = boto.s3.Connection( - aws_access_key_id='test:tester', - aws_secret_access_key='testing', - port=8080, - host='127.0.0.1', - is_secure=False, - calling_format=boto.s3.connection.OrdinaryCallingFormat()) - -
    -
    - - Managing OpenStack Object Storage with CLI - Swift - In the Object Store (swift) project there is a tool that - can perform a variety of tasks on your storage cluster - named swift. This client utility can be used for adhoc - processing, to gather statistics, list items, update - metadata, upload, download and delete files. It is based - on the native swift client library client.py. - Incorporating client.py into swift provides many benefits - such as seamlessly re-authorizing if the current token - expires in the middle of processing, retrying operations - up to five times and a processing concurrency of 10. All - of these things help make the swift tool robust and great - for operational use. -
    - Swift ACLs - Swift ACLs work with users and accounts. Users have - roles on accounts - such as '.admin', which allows - full access to all containers and objects under the - account. ACLs are set at the container level and - support lists for read and write access, which are set - with the X-Container-Read and X-Container-Write header - respectively. - The swift client can be used to set the acls, using - the post subcommand with the option '-r' for the read - ACL, and '-w' for the write ACL. This example allows - the user 'testuser' to read objects in the container: - - $ swift post -r 'testuser' - - This could instead be a list of users. - If you are using the StaticWeb middleware to allow - OpenStack Object Storage to serve public web content, - you should also be aware of the ACL syntax for - managing allowed referrers. The syntax is '.r:' - followed by a list of allowed referrers. For example, - this command allows all referring domains access to - the object: - - $ swift post -r '.r:*' - - -
    -
    - Swift CLI Basics - The command line usage for swift, the CLI tool is: - swift (command) [options] [args] - - Here are the available commands for swift. - - stat [container] [object] - Displays information for the account, container, - or object depending on the args given (if - any). - - - list [options] [container] - Lists the containers for the account or the - objects for a container. -p or -prefix is an - option that will only list items beginning with - that prefix. -d or -delimiter is option (for - container listings only) that will roll up items - with the given delimiter, or character that can - act as a nested directory organizer. - - - upload [options] container file_or_directory - [file_or_directory] […] - Uploads to the given container the files and - directories specified by the remaining args. -c or - -changed is an option that will only upload files - that have changed since the last upload. - - - post [options] [container] [object] - Updates meta information for the account, - container, or object depending on the args given. - If the container is not found, it will be created - automatically; but this is not true for accounts - and objects. Containers also allow the -r (or - -read-acl) and -w (or -write-acl) options. The -m - or -meta option is allowed on all and used to - define the user meta data items to set in the form - Name:Value. This option can be repeated. - Example: post -m Color:Blue -m Size:Large - - - download —all OR download container [object] - [object] … - Downloads everything in the account (with —all), - or everything in a container, or a list of objects - depending on the args given. For a single object - download, you may use the -o [—output] (filename) - option to redirect the output to a specific file - or if “-” then just redirect to stdout. - - - delete —all OR delete container [object] - [object] … - Deletes everything in the account (with —all), - or everything in a container, or a list of objects - depending on the args given. - Example: swift -A - https://auth.api.rackspacecloud.com/v1.0 -U user - -K key stat - - - Options for swift - -version show program’s version number and - exit - -h, -help show this help message and exit - -s, -snet Use SERVICENET internal network - -v, -verbose Print more info - -q, -quiet Suppress status output - -A AUTH, -auth=AUTH URL for obtaining an auth - token - -U USER, -user=USER User name for obtaining an - auth token - -K KEY, -key=KEY Key for obtaining an auth - token - -
    -
    - Analyzing Log Files with Swift CLI - When you want quick, command-line answers to - questions about logs, you can use swift with the -o or - -output option. The -o —output option can only be used - with a single object download to redirect the data - stream to either a different file name or to STDOUT - (-). The ability to redirect the output to STDOUT - allows you to pipe “|” data without saving it to disk - first. One common use case is being able to do some - quick log file analysis. First let’s use swift to - setup some data for the examples. The “logtest” - directory contains four log files with the following - line format. - - Files: - 2010-11-16-21_access.log - 2010-11-16-22_access.log - 2010-11-15-21_access.log - 2010-11-15-22_access.log - - Log lines: - Nov 15 21:53:52 lucid64 proxy-server - 127.0.0.1 15/Nov/2010/22/53/52 DELETE /v1/AUTH_cd4f57824deb4248a533f2c28bf156d3/2eefc05599d44df38a7f18b0b42ffedd HTTP/1.0 204 - \ -- test%3Atester%2CAUTH_tkcdab3c6296e249d7b7e2454ee57266ff - - - txaba5984c-aac7-460e-b04b-afc43f0c6571 - 0.0432 - - - The swift tool can easily upload the four log files - into a container named “logtest”: - -$ cd logs -$ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing upload logtest *.log - - -2010-11-16-21_access.log -2010-11-16-22_access.log -2010-11-15-21_access.log -2010-11-15-22_access.log - - Get statistics on the account: $ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing -q stat - -Account: AUTH_cd4f57824deb4248a533f2c28bf156d3 -Containers: 1 -Objects: 4 -Bytes: 5888268 - - Get statistics on the container: - $ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing stat logtest Account: AUTH_cd4f57824deb4248a533f2c28bf156d3 -Container: logtest -Objects: 4 -Bytes: 5864468 -Read ACL: -Write ACL: - - List all the objects in the container: - $ swift -A http:///swift-auth.com:11000/v1.0 -U test:tester -K testing list logtest2010-11-15-21_access.log -2010-11-15-22_access.log -2010-11-16-21_access.log -2010-11-16-22_access.log - - The following examples use the -o —output option - with (-) to help answer questions about the uploaded - log files. The swift command will download an object, - stream it to awk to determine the breakdown of - requests by return code for everything during 2200 on - November 16th, 2010. Based on the log line format - column 9 is the type of request and column 12 is the - return code. After awk processes the data stream it is - piped to sort and then uniq -c to sum up the number of - occurrences for each combination of request type and - return code. - -$ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing download -o - logtest 2010-11-16-22_access.log | awk ‘{ print $9”-“$12}’ | sort | uniq -c - - 805 DELETE-204 -12 DELETE-404 -2 DELETE-409 -723 GET-200 -142 GET-204 -74 GET-206 -80 GET-304 -34 GET-401 -5 GET-403 -18 GET-404 -166 GET-412 -2 GET-416 -50 HEAD-200 -17 HEAD-204 -20 HEAD-401 -8 HEAD-404 -30 POST-202 -25 POST-204 -22 POST-400 -6 POST-404 -842 PUT-201 -2 PUT-202 -32 PUT-400 -4 PUT-403 -4 PUT-404 -2 PUT-411 -6 PUT-412 -6 PUT-413 -2 PUT-422 -8 PUT-499 - - This example uses a bash for loop with awk, swift - with its -o —output option with a hyphen (-) to find - out how many PUT requests are in each log file. First - create a list of objects by running swift with the - list command on the “logtest” container; then for each - item in the list run swift with download -o - then - pipe the output into grep to filter the put requests - and finally into wc -l to count the lines. - - $ for f in `swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing list logtest` ; \ - do echo -ne “PUTS - ” ; swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing download -o - logtest $f | grep PUT | wc -l ; \ - done - -2010-11-15-21_access.log - PUTS - 402 -2010-11-15-22_access.log - PUTS - 1091 -2010-11-16-21_access.log - PUTS - 892 -2010-11-16-22_access.log - PUTS - 910 - - - By adding the -p —prefix option a prefix query is - performed on the list to return only the object names - that begin with a specific string. Let’s determine out - how many PUT requests are in each object with a name - beginning with “2010-11-15”. First create a list of - objects by running swift with the list command on the - “logtest” container with the prefix option -p - 2010-11-15. Then on each of item(s) returned run swift - with the download -o - then pipe the output to grep - and wc as in the previous example. The echo command is - added to display the object name. - - $ for f in `swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing list -p 2010-11-15 logtest` ; \ - do echo -ne “$f - PUTS - ” ; swift -A http://127.0.0.1:11000/v1.0 -U test:tester -K testing download -o - logtest $f | grep PUT | wc -l ; \ - done - 2010-11-15-21_access.log - PUTS - 402 -2010-11-15-22_access.log - PUTS - 910 - - The swift utility is simple, scalable, flexible and - provides useful solutions all of which are core - principles of cloud computing; with the -o output - option being just one of its many features. -
    -
    -
    diff --git a/doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml b/doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml deleted file mode 100644 index 78d8380896..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/objectstoragetutorials.xml +++ /dev/null @@ -1,182 +0,0 @@ - - - - OpenStack Object Storage Tutorials - We want people to use OpenStack for practical problem solving, and the increasing size and - density of web content makes for a great use-case for object storage. These tutorials show - you how to use your OpenStack Object Storage installation for practical purposes, and it - assumes Object Storage is already installed. -
    - - Storing Large Photos or Videos on the Cloud - - In this OpenStack tutorial, we’ll walk through using an Object Storage installation to - back up all your photos or videos. As the sensors on consumer-grade and pro-sumer grade - cameras generate more and more megapixels, we all need a place to back our files to and - know they are safe. - - We'll go through this tutorial in parts: - - - Setting up secure access to Object Storage. - Configuring Cyberduck for connecting to OpenStack Object Storage. - Copying files to the cloud. - -
    - Part I: Setting Up Secure Access - In this part, we'll get the proxy server running with SSL on the Object Storage - installation. It's a requirement for using Cyberduck as a client interface to Object - Storage. - You will need a key and certificate to do this, which we can create as a - self-signed for the tutorial since we can do the extra steps to have Cyberduck - accept it. Creating a self-signed cert can usually be done with these commands on - the proxy server: - $ cd /etc/swift -$ openssl req -new -x509 -nodes -out cert.crt -keyout cert.key - - Ensure these generated files are in /etc/swift/cert.crt and /etc/swift/cert.key. - You also should configure your iptables to enable https traffic. Here's an example - setup that works. - Chain INPUT (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination -76774 1543M ACCEPT all -- lo any localhost anywhere - 416K 537M ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED - 106 6682 ACCEPT tcp -- any any anywhere anywhere tcp dpt:https - 13 760 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh - 3 124 ACCEPT icmp -- any any anywhere anywhere icmp echo-request - 782 38880 DROP all -- any any anywhere anywhere - -Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) - pkts bytes target prot opt in out source destination - 0 0 DROP all -- any any anywhere anywhere - -Chain OUTPUT (policy ACCEPT 397K packets, 1561M bytes) - pkts bytes target prot opt in out source destination - If you don't have access to the Object Storage installation to configure these - settings, ask your service provider to set up secure access for you.Then, edit your proxy-server.conf file to - include the following in the [DEFAULT] sections. - -[DEFAULT] -bind_port = 443 -cert_file = /etc/swift/cert.crt -key_file = /etc/swift/cert.key - - Also, make sure you use https: for all references to the URL for the server in the - .conf files as needed. - Verify that you can connect using the Public URL to Object Storage by using the - "swift" tool: - - $ swift -A https://yourswiftinstall.com:11000/v1.0 -U test:tester -K testing stat - - - Okay, you've created the access that Cyberduck expects for your Object Storage - installation. Let's start configuring the Cyberduck side of things. - -
    -
    - - Part II: Configuring Cyberduck - - - See the Cyberduck website - for further details. - - - - After installing Cyberduck you'll need to change the path/context - used for the authentication URL. The default value shipped with - Cyberduck is incorrect. - - - On OS X open a Terminal window and execute, - $ defaults write ch.sudo.cyberduck cf.authentication.context /auth/v1.0 - - On Windows open the preferences file in a text - editor. The exact location of this file is described - here. If this path doesn't exist you may - need to start and stop Cyberduck to have it generate - the config file. Once you've opened the file add the - setting, - <setting name="cf.authentication.context" value="/auth/v1.0" /> - - - To connect to Swift start Cyberduck and click the - Open Connection toolbar button or choose - File > Open Connection. Select - Swift (OpenStack Object Storage) in the - dropdown and enter your cluster details. - - - Server - - your proxy server's hostname or IP address - - - - Port - 443 - - - Username - - - account name followed by a colon and then the user name, - for example test:tester - - - - - Password - - - password for the account and user name entered above - - - - -
    - Example Cyberduck Swift Connection - - - - - -
    -
    - - - Connecting to a Unsecured Swift Cluster - An Unsecured Swift Cluster does not use https - connections. Download the Unsecured Swift profile file and - double click it to import it into Cyberduck. - - When creating a new connection select Swift (HTTP). - Enter your connection details as described above. You'll need - to change the port since presumably you won't want to use 443. - - -
    -
    - Part III: Creating Containers (Folders) and Uploading Files - Now you want to create containers to hold your files. Without containers, Object - Storage doesn't know where to put the files. In the Action menu, choose New Folder - and name the folder. - Next you can drag and drop files into the created folder or select File > Upload - to select files to upload to the OpenStack Object Storage service.
    - Example Cyberduck Swift Showing Uploads - - - - - -
    Et voila! You can back up terabytes of data if you just have the space and the data. That's a lot of pictures or video, so get snapping and rolling! -
    -
    -
    diff --git a/doc/src/docbkx/openstack-object-storage-admin/pom.xml b/doc/src/docbkx/openstack-object-storage-admin/pom.xml deleted file mode 100644 index b6628778d4..0000000000 --- a/doc/src/docbkx/openstack-object-storage-admin/pom.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - 4.0.0 - - org.openstack.docs - openstack-guide - 1.0.0-SNAPSHOT - jar - OpenStack Administration Guides - - - - local - 1 - - - - - - - - - com.rackspace.cloud.api - clouddocs-maven-plugin - 1.9.2 - - - generate-webhelp - - generate-webhelp - - generate-sources - - - ${comments.enabled} - os-object-admin - 1 - UA-17511903-1 - appendix toc,title - article/appendix nop - article toc,title - book title,figure,table,example,equation - chapter toc,title - section toc part - toc,title - preface toc,title - qandadiv toc - qandaset toc - reference toc,title - set toc,title - - 0 - 1 - 0 - admin - ${basedir}/target/docbkx/webhelp/${release.path.name}/openstack-object-storage - 0 - os-objectstorage-adminguide-${release.path.name} - - - - cleanup - - generate-webhelp - - generate-sources - - dummy.xml - - - - - - - - - - - - - - true - . - bk-objectstorage-adminguide.xml - http://docs.openstack.org/${release.path.name}/openstack-object-storage/admin/content/ - reviewer - openstack - - - - - - - Rackspace Research Repositories - - true - - - - rackspace-research - Rackspace Research Repository - http://maven.research.rackspacecloud.com/content/groups/public/ - - - - - rackspace-research - Rackspace Research Repository - http://maven.research.rackspacecloud.com/content/groups/public/ - - - - - diff --git a/doc/src/docbkx/openstack-user-admin/src/ch_cli.xml b/doc/src/docbkx/openstack-user-admin/src/ch_cli.xml index 627f2ff7dc..14efcf9dbc 100644 --- a/doc/src/docbkx/openstack-user-admin/src/ch_cli.xml +++ b/doc/src/docbkx/openstack-user-admin/src/ch_cli.xml @@ -31,4 +31,6 @@ + + diff --git a/doc/src/docbkx/openstack-user-admin/src/section_swift_cli_analyze_log_files.xml b/doc/src/docbkx/openstack-user-admin/src/section_swift_cli_analyze_log_files.xml new file mode 100644 index 0000000000..edc1985caa --- /dev/null +++ b/doc/src/docbkx/openstack-user-admin/src/section_swift_cli_analyze_log_files.xml @@ -0,0 +1,151 @@ + +
    + Analyzing Log Files with Swift CLI + When you want quick, command-line answers to + questions about logs, you can use swift with the -o or + -output option. The -o —output option can only be used + with a single object download to redirect the data + stream to either a different file name or to STDOUT + (-). The ability to redirect the output to STDOUT + allows you to pipe “|” data without saving it to disk + first. One common use case is being able to do some + quick log file analysis. First let’s use swift to + setup some data for the examples. The “logtest” + directory contains four log files with the following + line format. + + Files: + 2010-11-16-21_access.log + 2010-11-16-22_access.log + 2010-11-15-21_access.log + 2010-11-15-22_access.log + + Log lines: + Nov 15 21:53:52 lucid64 proxy-server - 127.0.0.1 15/Nov/2010/22/53/52 DELETE /v1/AUTH_cd4f57824deb4248a533f2c28bf156d3/2eefc05599d44df38a7f18b0b42ffedd HTTP/1.0 204 - \ +- test%3Atester%2CAUTH_tkcdab3c6296e249d7b7e2454ee57266ff - - - txaba5984c-aac7-460e-b04b-afc43f0c6571 - 0.0432 + + + The swift tool can easily upload the four log files + into a container named “logtest”: + +$ cd logs +$ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing upload logtest *.log + + +2010-11-16-21_access.log +2010-11-16-22_access.log +2010-11-15-21_access.log +2010-11-15-22_access.log + + Get statistics on the account: $ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing -q stat + +Account: AUTH_cd4f57824deb4248a533f2c28bf156d3 +Containers: 1 +Objects: 4 +Bytes: 5888268 + + Get statistics on the container: + $ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing stat logtest Account: AUTH_cd4f57824deb4248a533f2c28bf156d3 +Container: logtest +Objects: 4 +Bytes: 5864468 +Read ACL: +Write ACL: + + List all the objects in the container: + $ swift -A http:///swift-auth.com:11000/v1.0 -U test:tester -K testing list logtest2010-11-15-21_access.log +2010-11-15-22_access.log +2010-11-16-21_access.log +2010-11-16-22_access.log + + The following examples use the -o —output option + with (-) to help answer questions about the uploaded + log files. The swift command will download an object, + stream it to awk to determine the breakdown of + requests by return code for everything during 2200 on + November 16th, 2010. Based on the log line format + column 9 is the type of request and column 12 is the + return code. After awk processes the data stream it is + piped to sort and then uniq -c to sum up the number of + occurrences for each combination of request type and + return code. + +$ swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing download -o - logtest 2010-11-16-22_access.log | awk ‘{ print $9”-“$12}’ | sort | uniq -c + + 805 DELETE-204 +12 DELETE-404 +2 DELETE-409 +723 GET-200 +142 GET-204 +74 GET-206 +80 GET-304 +34 GET-401 +5 GET-403 +18 GET-404 +166 GET-412 +2 GET-416 +50 HEAD-200 +17 HEAD-204 +20 HEAD-401 +8 HEAD-404 +30 POST-202 +25 POST-204 +22 POST-400 +6 POST-404 +842 PUT-201 +2 PUT-202 +32 PUT-400 +4 PUT-403 +4 PUT-404 +2 PUT-411 +6 PUT-412 +6 PUT-413 +2 PUT-422 +8 PUT-499 + + This example uses a bash for loop with awk, swift + with its -o —output option with a hyphen (-) to find + out how many PUT requests are in each log file. First + create a list of objects by running swift with the + list command on the “logtest” container; then for each + item in the list run swift with download -o - then + pipe the output into grep to filter the put requests + and finally into wc -l to count the lines. + + $ for f in `swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing list logtest` ; \ + do echo -ne “PUTS - ” ; swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing download -o - logtest $f | grep PUT | wc -l ; \ + done + +2010-11-15-21_access.log - PUTS - 402 +2010-11-15-22_access.log - PUTS - 1091 +2010-11-16-21_access.log - PUTS - 892 +2010-11-16-22_access.log - PUTS - 910 + + + By adding the -p —prefix option a prefix query is + performed on the list to return only the object names + that begin with a specific string. Let’s determine out + how many PUT requests are in each object with a name + beginning with “2010-11-15”. First create a list of + objects by running swift with the list command on the + “logtest” container with the prefix option -p + 2010-11-15. Then on each of item(s) returned run swift + with the download -o - then pipe the output to grep + and wc as in the previous example. The echo command is + added to display the object name. + + $ for f in `swift -A http://swift-auth.com:11000/v1.0 -U test:tester -K testing list -p 2010-11-15 logtest` ; \ + do echo -ne “$f - PUTS - ” ; swift -A http://127.0.0.1:11000/v1.0 -U test:tester -K testing download -o - logtest $f | grep PUT | wc -l ; \ + done + 2010-11-15-21_access.log - PUTS - 402 +2010-11-15-22_access.log - PUTS - 910 + + The swift utility is simple, scalable, flexible and + provides useful solutions all of which are core + principles of cloud computing; with the -o output + option being just one of its many features. +
    diff --git a/doc/src/docbkx/openstack-user/src/section_swift_cli_howto.xml b/doc/src/docbkx/openstack-user/src/section_swift_cli_howto.xml new file mode 100644 index 0000000000..eb1368c140 --- /dev/null +++ b/doc/src/docbkx/openstack-user/src/section_swift_cli_howto.xml @@ -0,0 +1,52 @@ + +
    + Managing OpenStack Object Storage with CLI + Swift + In the Object Store (swift) project there is a tool that + can perform a variety of tasks on your storage cluster + named swift. This client utility can be used for adhoc + processing, to gather statistics, list items, update + metadata, upload, download and delete files. It is based + on the native swift client library client.py. + Incorporating client.py into swift provides many benefits + such as seamlessly re-authorizing if the current token + expires in the middle of processing, retrying operations + up to five times and a processing concurrency of 10. All + of these things help make the swift tool robust and great + for operational use. +
    + Swift ACLs + Swift ACLs work with users and accounts. Users have + roles on accounts - such as '.admin', which allows + full access to all containers and objects under the + account. ACLs are set at the container level and + support lists for read and write access, which are set + with the X-Container-Read and X-Container-Write header + respectively. + The swift client can be used to set the acls, using + the post subcommand with the option '-r' for the read + ACL, and '-w' for the write ACL. This example allows + the user 'testuser' to read objects in the container: + + $ swift post -r 'testuser' + + This could instead be a list of users. + If you are using the StaticWeb middleware to allow + OpenStack Object Storage to serve public web content, + you should also be aware of the ACL syntax for + managing allowed referrers. The syntax is '.r:' + followed by a list of allowed referrers. For example, + this command allows all referring domains access to + the object: + + $ swift post -r '.r:*' + + +
    + +