Initial commit.
This initial commit only targets a single node swift install on Natty based on 1.4.6
This commit is contained in:
commit
47d49e7780
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
148
README
Normal file
148
README
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
==Disclaimer
|
||||||
|
|
||||||
|
This is not ready to be used.
|
||||||
|
|
||||||
|
This is pre-beta code that is actively being developed.
|
||||||
|
|
||||||
|
It is currently being developed against swift trunk.
|
||||||
|
|
||||||
|
I am actively seeking users who understand that this code
|
||||||
|
is in a pre-alpha state. Feel free to contact me (Dan Bode)
|
||||||
|
at dan < at > puppetlabs <dot> com or bodepd < on > freenode.
|
||||||
|
|
||||||
|
Any feedback greatly appreciated.
|
||||||
|
|
||||||
|
==Dependencies
|
||||||
|
|
||||||
|
This module has the following dependencies:
|
||||||
|
|
||||||
|
https://github.com/bodepd/puppet-ssh
|
||||||
|
(this should actaully depend on https://github.com/saz/puppet-ssh
|
||||||
|
and can when pull request https://github.com/saz/puppet-ssh/pull/1
|
||||||
|
is merged)
|
||||||
|
https://github.com/bodepd/puppet-rsync
|
||||||
|
(there is a pull request to merge this into the parent repo:
|
||||||
|
https://github.com/bodepd/puppet-rsync)
|
||||||
|
https://github.com/saz/puppet-memcached
|
||||||
|
https://github.com/puppetlabs/puppetlabs-stdlib
|
||||||
|
|
||||||
|
This module has only been tested on Ubuntu Natty, with Puppet 2.7.9
|
||||||
|
|
||||||
|
this module is intended to complement other openstack modules and
|
||||||
|
will eventually be a submodule of the openstack set of modules:
|
||||||
|
|
||||||
|
https://github.com/puppetlabs/puppetlabs-openstack
|
||||||
|
|
||||||
|
These modules have only been verified as working against the
|
||||||
|
Swift all in one installation instructions: http://swift.openstack.org/development_saio.html
|
||||||
|
|
||||||
|
They have also only been tested for 1.4.6 (and will probably not work for Diablo... yet)
|
||||||
|
|
||||||
|
==Usage:
|
||||||
|
|
||||||
|
swift:
|
||||||
|
|
||||||
|
class that sets up base packages and the base
|
||||||
|
/etc/swift/swift.conf.
|
||||||
|
|
||||||
|
class { 'swift':
|
||||||
|
# shared salt used when hashing ring mappings
|
||||||
|
swift_hash_suffix => 'shared_secret',
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::proxy:
|
||||||
|
|
||||||
|
class that installs and configures the swift
|
||||||
|
proxy server
|
||||||
|
|
||||||
|
class { 'swift::proxy':
|
||||||
|
# specifies that account should be automatically created
|
||||||
|
account_autocreate = true,
|
||||||
|
#proxy_local_net_ip = '127.0.0.1',
|
||||||
|
#proxy_port = '11211',
|
||||||
|
# auth type defaults to tempauth - this is the
|
||||||
|
# only auth that has been tested
|
||||||
|
#auth_type = 'tempauth',
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage
|
||||||
|
|
||||||
|
class that sets up all of the configuration and dependencies
|
||||||
|
for swift storage instances
|
||||||
|
|
||||||
|
class { 'swift::storage':
|
||||||
|
# address that swift should bind to
|
||||||
|
storage_local_net_ip => '127.0.0.1'
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::device
|
||||||
|
|
||||||
|
defined resource type that can be used to
|
||||||
|
indicate a specific device to be managed
|
||||||
|
|
||||||
|
This will configure the rsync server instance
|
||||||
|
and swift storage instance to manage the device (which
|
||||||
|
basically maps port to device)
|
||||||
|
|
||||||
|
# the title for this device is the port where it
|
||||||
|
# will be hosted
|
||||||
|
swift::storage::device { '6010'
|
||||||
|
# the type of device (account/object/container)
|
||||||
|
type => 'object',
|
||||||
|
# directory where device is mounted
|
||||||
|
devices = '/srv/node',
|
||||||
|
# address to bind to
|
||||||
|
storage_local_net_ip = '127.0.0.1'
|
||||||
|
) {
|
||||||
|
|
||||||
|
swift::storage::loopback
|
||||||
|
|
||||||
|
This defined resource was created to test
|
||||||
|
swift by creating loopback devices that can be
|
||||||
|
used for testing
|
||||||
|
|
||||||
|
It creates a partition of size [$seek]
|
||||||
|
at base_dir/[$name] using dd with [$byte_size],
|
||||||
|
formats it to be an xfs
|
||||||
|
filesystem which is mounted at /src/node/[$name]
|
||||||
|
|
||||||
|
It then creates swift::storage::devices for each device
|
||||||
|
type using the title as the 3rd digit of
|
||||||
|
a four digit port number
|
||||||
|
|
||||||
|
60[digit][role] (object = 0, container = 1, account = 2)
|
||||||
|
|
||||||
|
swift::storage::loopback { '1':
|
||||||
|
base_dir = '/srv/loopback-device',
|
||||||
|
mnt_base_dir = '/srv/node',
|
||||||
|
byte_size = '1024',
|
||||||
|
seek = '25000',
|
||||||
|
storage_local_net_ip = '127.0.0.1'
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::ringbuiler
|
||||||
|
|
||||||
|
class that knows how to build rings. This only exists as a vague idea
|
||||||
|
|
||||||
|
the ring building will like be built as a combination of native types
|
||||||
|
(for adding the drives) and defined types for rebalancing
|
||||||
|
|
||||||
|
==Example
|
||||||
|
|
||||||
|
For an example of how to use this module to build out a single node
|
||||||
|
swift cluster, you can try running puppet apply examples/site.pp
|
||||||
|
(feel free to look at the code to see how to use this module)
|
||||||
|
|
||||||
|
There are a few known issues with this code:
|
||||||
|
|
||||||
|
- for some reason the ringbuilding script does not run
|
||||||
|
after the manifest fails, you still need to login
|
||||||
|
and run bash /etc/swift/ringbuilder.sh and start swift-proxy
|
||||||
|
- once swift is running, you can test the swift instance with the
|
||||||
|
ruby script stored in files/swift_tester.rb
|
||||||
|
|
||||||
|
This example can be used as follows:
|
||||||
|
|
||||||
|
puppet apply examples/site.pp --certname pre_swift
|
||||||
|
|
||||||
|
puppet apply examples/site.pp --certname swift_all
|
14
Rakefile
Normal file
14
Rakefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
require 'rake'
|
||||||
|
|
||||||
|
task :default => [:spec]
|
||||||
|
|
||||||
|
desc "Run all module spec tests (Requires rspec-puppet gem)"
|
||||||
|
task :spec do
|
||||||
|
system("rspec spec/**/*_spec.rb")
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Build package"
|
||||||
|
task :build do
|
||||||
|
system("puppet-module build")
|
||||||
|
end
|
||||||
|
|
30
TODO
Normal file
30
TODO
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
*
|
||||||
|
Disclaimer - this does not work yet.
|
||||||
|
|
||||||
|
I will make a release when I feel like things are coming together.
|
||||||
|
|
||||||
|
I am only releasing this on github, b/c people are interested in the
|
||||||
|
code dispite the fact that it does not quite work yet.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
|
||||||
|
This currently only works on ubuntu releases that
|
||||||
|
can configure swift using upstart
|
||||||
|
|
||||||
|
|
||||||
|
swift is currently not using ssl for transport b/c I did not create
|
||||||
|
self signed certs as a part of the installation
|
||||||
|
(also swift proxy is not configured to use those certs)
|
||||||
|
|
||||||
|
# not
|
||||||
|
|
||||||
|
# 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 = 26214
|
||||||
|
|
||||||
|
autocreate - should be set to true if tempauth is used
|
100
examples/site.pp
Normal file
100
examples/site.pp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#
|
||||||
|
# This example file is almost the
|
||||||
|
# same as what I have been using
|
||||||
|
# to build swift in my environment (which is based on vagrant)
|
||||||
|
|
||||||
|
$proxy_local_net_ip='127.0.0.1'
|
||||||
|
$swift_shared_secret='changeme'
|
||||||
|
Exec { logoutput => true }
|
||||||
|
|
||||||
|
# set up all of the pre steps
|
||||||
|
# this shoud be run
|
||||||
|
node pre_swift {
|
||||||
|
|
||||||
|
class { 'apt':}
|
||||||
|
# use the swift trunk ppa
|
||||||
|
class { 'swift::repo::trunk':}
|
||||||
|
|
||||||
|
# use our apt repo
|
||||||
|
apt::source { 'puppet':
|
||||||
|
location => 'http://apt.puppetlabs.com/ubuntu',
|
||||||
|
release => 'natty',
|
||||||
|
key => '4BD6EC30',
|
||||||
|
}
|
||||||
|
# install the latest version of Puppet
|
||||||
|
package { 'puppet':
|
||||||
|
ensure => latest,
|
||||||
|
require => Apt::Source['puppet'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node swift_all {
|
||||||
|
# install curl (we will need it for testing)
|
||||||
|
package { 'curl': ensure => present }
|
||||||
|
|
||||||
|
# ensure that sshd is installed
|
||||||
|
class { 'ssh::server::install': }
|
||||||
|
|
||||||
|
# install memcached for the proxy
|
||||||
|
class { 'memcached':
|
||||||
|
listen_ip => $proxy_local_net_ip,
|
||||||
|
}
|
||||||
|
|
||||||
|
# set up the swift base deps
|
||||||
|
class { 'swift':
|
||||||
|
# not sure how I want to deal with this shared secret
|
||||||
|
swift_hash_suffix => $swift_shared_secret,
|
||||||
|
package_ensure => latest,
|
||||||
|
}
|
||||||
|
|
||||||
|
# configure base deps for storage
|
||||||
|
class { 'swift::storage': }
|
||||||
|
|
||||||
|
# set up three loopback devices for testing
|
||||||
|
swift::storage::loopback { ['1', '2', '3']:
|
||||||
|
require => Class['swift'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# this is just here temporarily until I can better figure out how to model it
|
||||||
|
file { '/etc/swift/ringbuilder.sh':
|
||||||
|
content => '
|
||||||
|
#!/bin/bash
|
||||||
|
# sets up a basic ring-builder
|
||||||
|
# which is hard-coded to only work
|
||||||
|
# for this example
|
||||||
|
|
||||||
|
cd /etc/swift
|
||||||
|
|
||||||
|
rm -f *.builder *.ring.gz backups/*.builder backups/*.ring.gz
|
||||||
|
|
||||||
|
swift-ring-builder object.builder create 18 3 1
|
||||||
|
swift-ring-builder object.builder add z1-127.0.0.1:6010/1 1
|
||||||
|
swift-ring-builder object.builder add z2-127.0.0.1:6020/2 1
|
||||||
|
swift-ring-builder object.builder add z3-127.0.0.1:6030/3 1
|
||||||
|
swift-ring-builder object.builder rebalance
|
||||||
|
swift-ring-builder container.builder create 18 3 1
|
||||||
|
swift-ring-builder container.builder add z1-127.0.0.1:6011/1 1
|
||||||
|
swift-ring-builder container.builder add z2-127.0.0.1:6021/2 1
|
||||||
|
swift-ring-builder container.builder add z3-127.0.0.1:6031/3 1
|
||||||
|
swift-ring-builder container.builder rebalance
|
||||||
|
swift-ring-builder account.builder create 18 3 1
|
||||||
|
swift-ring-builder account.builder add z1-127.0.0.1:6012/1 1
|
||||||
|
swift-ring-builder account.builder add z2-127.0.0.1:6022/2 1
|
||||||
|
swift-ring-builder account.builder add z3-127.0.0.1:6032/3 1
|
||||||
|
swift-ring-builder account.builder rebalance
|
||||||
|
',
|
||||||
|
mode => '555',
|
||||||
|
}~>
|
||||||
|
# TODO - figure out why this is failing ;(
|
||||||
|
exec { 'build-ring':
|
||||||
|
command => '/etc/swift/ringbuilder.sh',
|
||||||
|
refreshonly => true,
|
||||||
|
notify => Service['swift-proxy']
|
||||||
|
}
|
||||||
|
|
||||||
|
# configure swift proxy after the run is build
|
||||||
|
class { 'swift::proxy':
|
||||||
|
account_autocreate => true,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
files/ringbuilder.sh
Normal file
21
files/ringbuilder.sh
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd /etc/swift
|
||||||
|
|
||||||
|
rm -f *.builder *.ring.gz backups/*.builder backups/*.ring.gz
|
||||||
|
|
||||||
|
swift-ring-builder object.builder create 18 3 1
|
||||||
|
swift-ring-builder object.builder add z1-127.0.0.1:6010/sdb1 1
|
||||||
|
swift-ring-builder object.builder add z2-127.0.0.1:6020/sdb2 1
|
||||||
|
swift-ring-builder object.builder add z3-127.0.0.1:6030/sdb3 1
|
||||||
|
swift-ring-builder object.builder rebalance
|
||||||
|
swift-ring-builder container.builder create 18 3 1
|
||||||
|
swift-ring-builder container.builder add z1-127.0.0.1:6011/sdb1 1
|
||||||
|
swift-ring-builder container.builder add z2-127.0.0.1:6021/sdb2 1
|
||||||
|
swift-ring-builder container.builder add z3-127.0.0.1:6031/sdb3 1
|
||||||
|
swift-ring-builder container.builder rebalance
|
||||||
|
swift-ring-builder account.builder create 18 3 1
|
||||||
|
swift-ring-builder account.builder add z1-127.0.0.1:6012/sdb1 1
|
||||||
|
swift-ring-builder account.builder add z3-127.0.0.1:6022/sdb2 1
|
||||||
|
swift-ring-builder account.builder add z4-127.0.0.1:6032/sdb3 1
|
||||||
|
swift-ring-builder account.builder rebalance
|
118
files/swift_tester.rb
Normal file
118
files/swift_tester.rb
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
#
|
||||||
|
# This is a script that uses
|
||||||
|
# instructions here: http://swift.openstack.org/howto_installmultinode.html
|
||||||
|
# Even though I expect this script will work with a wide range
|
||||||
|
# of swift versions, it is currently only tested with: 1.4.6
|
||||||
|
require 'open3'
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
# connection variables
|
||||||
|
proxy_local_net_ip='127.0.0.1'
|
||||||
|
user='test:tester'
|
||||||
|
password='testing'
|
||||||
|
|
||||||
|
# headers for curl requests
|
||||||
|
user_header="-H 'X-Storage-User: #{user}'"
|
||||||
|
password_header="-H 'X-Storage-Pass: #{password}'"
|
||||||
|
get_cred_command="curl -k -v #{user_header} #{password_header} http://#{proxy_local_net_ip}:8080/auth/v1.0"
|
||||||
|
|
||||||
|
# verify that we can retrive credentials from our user
|
||||||
|
result_hash = {}
|
||||||
|
puts "getting credentials: #{get_cred_command}"
|
||||||
|
Open3.popen3(get_cred_command) do |stdin, stdout, stderr|
|
||||||
|
result_hash[:stderr] = stderr.read
|
||||||
|
result_hash[:stderr].split("\n").each do |line|
|
||||||
|
if line =~ /^< HTTP\/\d\.\d (\d\d\d)/
|
||||||
|
result_hash[:status_code]=$1
|
||||||
|
end
|
||||||
|
if line =~ /< X-Storage-Url: (http\S+)/
|
||||||
|
result_hash[:auth_url]=$1
|
||||||
|
end
|
||||||
|
if line =~ /< X-Storage-Token: (AUTH_\S+)/
|
||||||
|
result_hash[:auth_token]=$1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
raise(Exception, "Call to get auth tokens failed:\n#{result_hash[:stderr]}") unless result_hash[:status_code] == '200'
|
||||||
|
|
||||||
|
# verify that the credentials are valid
|
||||||
|
auth_token_header="-H 'X-Auth-Token: #{result_hash[:auth_token]}'"
|
||||||
|
get_account_head="curl -k -v #{auth_token_header} #{result_hash[:auth_url]}"
|
||||||
|
# what is the expected code?
|
||||||
|
puts "verifying connection auth: #{get_account_head}"
|
||||||
|
Open3.popen3(get_account_head) do |stdin, stdout, stderr|
|
||||||
|
#puts stdout.read
|
||||||
|
#puts stderr.read
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
proxy_local_net_ip='127.0.0.1'
|
||||||
|
user='test:tester'
|
||||||
|
password='testing'
|
||||||
|
swift_command_prefix="swift -A http://#{proxy_local_net_ip}:8080/auth/v1.0 -U #{user} -K #{password}"
|
||||||
|
|
||||||
|
swift_test_command="#{swift_command_prefix} stat"
|
||||||
|
|
||||||
|
puts "Testing swift: #{swift_test_command}"
|
||||||
|
status_hash={}
|
||||||
|
Open3.popen3(swift_test_command) do |stdin, stdout, stderr|
|
||||||
|
status_hash[:stdout] = stdout.read
|
||||||
|
status_hash[:stderr] = stderr.read
|
||||||
|
status_hash[:stdout].split("\n").each do |line|
|
||||||
|
if line =~ /\s*Containers:\s+(\d+)/
|
||||||
|
status_hash[:containers] = $1
|
||||||
|
end
|
||||||
|
if line =~ /\s*Objects:\s+(\d+)/
|
||||||
|
status_hash[:objects] = $1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unless(status_hash[:containers] =~ /\d+/ and status_hash[:objects] =~ /\d+/)
|
||||||
|
raise(Exception, "Expected to find the number of containers/objects:\n#{status_hash[:stdout]}\n#{status_hash[:stderr]}")
|
||||||
|
else
|
||||||
|
puts "found containers/objects: #{status_hash[:containers]}/#{status_hash[:objects]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# test that we can upload something
|
||||||
|
File.open('/tmp/foo1', 'w') do |fh|
|
||||||
|
fh.write('test1')
|
||||||
|
end
|
||||||
|
|
||||||
|
container = 'my_container'
|
||||||
|
|
||||||
|
swift_upload_command="#{swift_command_prefix} upload #{container} /tmp/foo1"
|
||||||
|
puts "Uploading file to swift with command: #{swift_upload_command}"
|
||||||
|
|
||||||
|
Open3.popen3(swift_upload_command) do |stdin, stdout, stderr|
|
||||||
|
puts stdout.read
|
||||||
|
puts stderr.read
|
||||||
|
end
|
||||||
|
|
||||||
|
# test that we can download the thing that we uploaded
|
||||||
|
download_test_dir = '/tmp/test/downloadtest/'
|
||||||
|
FileUtils.rm_rf download_test_dir
|
||||||
|
FileUtils.mkdir_p download_test_dir
|
||||||
|
|
||||||
|
swift_download_command="#{swift_command_prefix} download #{container}"
|
||||||
|
puts "Downloading file with command: #{swift_download_command}"
|
||||||
|
Dir.chdir(download_test_dir) do
|
||||||
|
Open3.popen3(swift_download_command) do |stdin, stdout, stderr|
|
||||||
|
puts stdout.read
|
||||||
|
puts stderr.read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
expected_file = File.join(download_test_dir, 'tmp', 'foo1')
|
||||||
|
|
||||||
|
if File.exists?(expected_file)
|
||||||
|
if File.read(expected_file) == 'test1'
|
||||||
|
puts "Dude!!!! It actually seems to work, we can upload and download files!!!!"
|
||||||
|
else
|
||||||
|
raise(Exception, "So close, but the contents of the downloaded file are not what I expected: Got: #{File.read(expected_file)}, expected: test1")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise(Exception, "file #{expected_file} did not exist somehow, probably b/c swift is not installed correctly")
|
||||||
|
end
|
||||||
|
|
71
manifests/init.pp
Normal file
71
manifests/init.pp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# Install and configure base swift components
|
||||||
|
# == Parameters
|
||||||
|
# [*swift_hash_suffix*] string of text to be used
|
||||||
|
# as a salt when hashing to determine mappings in the ring.
|
||||||
|
# This file should be the same on every node in the cluster!
|
||||||
|
#
|
||||||
|
# [*swift_ssh_key*] NOT YET IMPLEMENTED
|
||||||
|
#
|
||||||
|
|
||||||
|
class swift(
|
||||||
|
$swift_hash_suffix,
|
||||||
|
# $swift_ssh_key,
|
||||||
|
$package_ensure = 'present'
|
||||||
|
) {
|
||||||
|
|
||||||
|
# maybe I should just install ssh?
|
||||||
|
Class['ssh::server::install'] -> Class['swift']
|
||||||
|
|
||||||
|
package { 'swift':
|
||||||
|
ensure => $package_ensure,
|
||||||
|
}
|
||||||
|
|
||||||
|
File { owner => 'swift', group => 'swift', require => Package['swift'] }
|
||||||
|
|
||||||
|
file { '/home/swift':
|
||||||
|
ensure => directory,
|
||||||
|
mode => 0700,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift':
|
||||||
|
ensure => directory,
|
||||||
|
mode => 2770,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/var/run/swift':
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/swift.conf':
|
||||||
|
ensure => present,
|
||||||
|
mode => 0660,
|
||||||
|
content => template('swift/swift.conf.erb'),
|
||||||
|
}
|
||||||
|
|
||||||
|
# if ($swift_ssh_key) {
|
||||||
|
# if $swift_ssh_key !~ /^(ssh-...) +([^ ]*) *([^ \n]*)/ {
|
||||||
|
# err("Can't parse swift_ssh_key")
|
||||||
|
# notify { "Can't parse public key file $name on the keymaster: skipping ensure => $e
|
||||||
|
#nsure": }
|
||||||
|
# } else {
|
||||||
|
# $keytype = $1
|
||||||
|
# $modulus = $2
|
||||||
|
# $comment = $3
|
||||||
|
# ssh_authorized_key { $comment:
|
||||||
|
# ensure => "present",
|
||||||
|
# user => "swift",
|
||||||
|
# type => $keytype,
|
||||||
|
# key => $modulus,
|
||||||
|
# options => $options ? { "" => undef, default => $options },
|
||||||
|
# require => File["/home/swift"]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# does swift need an ssh key?
|
||||||
|
# they are adding one in the openstack modules
|
||||||
|
|
||||||
|
#
|
||||||
|
# I do not understand how to configure the rings
|
||||||
|
# or why rings would be configured on the proxy?
|
||||||
|
|
||||||
|
}
|
81
manifests/proxy.pp
Normal file
81
manifests/proxy.pp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#
|
||||||
|
# [*auth_type*] - specified the type of authorization to use.
|
||||||
|
# valid values are tempauth, swauth, and keystone. Optional
|
||||||
|
# Defaults to keystone
|
||||||
|
class swift::proxy(
|
||||||
|
# why did cloudbuilders default this to false?
|
||||||
|
$allow_account_management = true,
|
||||||
|
$account_autocreate = false,
|
||||||
|
$proxy_local_net_ip = '127.0.0.1',
|
||||||
|
$proxy_port = '11211',
|
||||||
|
$auth_type = 'tempauth',
|
||||||
|
$swauth_endpoint = '127.0.0.1',
|
||||||
|
$swauth_super_admin_key = 'swauthkey',
|
||||||
|
$package_ensure = 'present'
|
||||||
|
) inherits swift {
|
||||||
|
|
||||||
|
Class['memcached'] -> Class['swift::proxy']
|
||||||
|
|
||||||
|
validate_re($auth_type, 'tempauth|swauth|keystone')
|
||||||
|
|
||||||
|
if(auth_type == 'keystone') {
|
||||||
|
fail('Keystone is currently not supported, it should be supported soon :)')
|
||||||
|
}
|
||||||
|
|
||||||
|
if($user_swauth) {
|
||||||
|
package { 'python-swauth':
|
||||||
|
ensure => $package_ensure,
|
||||||
|
before => Package['swift-proxy'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
package { 'swift-proxy':
|
||||||
|
ensure => $package_ensure,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { "/etc/swift/proxy-server.conf":
|
||||||
|
ensure => present,
|
||||||
|
owner => 'swift',
|
||||||
|
group => 'swift',
|
||||||
|
mode => 0660,
|
||||||
|
content => template('swift/proxy-server.conf.erb'),
|
||||||
|
require => Package['swift-proxy'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO - this needs to be updated once the init file is not broken
|
||||||
|
|
||||||
|
file { '/etc/init/swift-proxy.conf':
|
||||||
|
mode => '0644',
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
content => '
|
||||||
|
# swift-proxy - SWIFT Proxy Server
|
||||||
|
# This is temporarily managed by Puppet
|
||||||
|
# until 917893 is fixed
|
||||||
|
# The swift proxy server.
|
||||||
|
|
||||||
|
description "SWIFT Proxy Server"
|
||||||
|
author "Marc Cluet <marc.cluet@ubuntu.com>"
|
||||||
|
|
||||||
|
start on runlevel [2345]
|
||||||
|
stop on runlevel [016]
|
||||||
|
|
||||||
|
pre-start script
|
||||||
|
if [ -f "/etc/swift/proxy-server.conf" ]; then
|
||||||
|
exec /usr/bin/swift-init proxy-server start
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
end script
|
||||||
|
|
||||||
|
post-stop exec /usr/bin/swift-init proxy-server stop',
|
||||||
|
before => Service['swift-proxy'],
|
||||||
|
}
|
||||||
|
|
||||||
|
service { 'swift-proxy':
|
||||||
|
ensure => running,
|
||||||
|
enable => true,
|
||||||
|
provider => 'upstart',
|
||||||
|
subscribe => File['/etc/swift/proxy-server.conf'],
|
||||||
|
}
|
||||||
|
}
|
6
manifests/repo/trunk.pp
Normal file
6
manifests/repo/trunk.pp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# sets up the swift trunk ppa
|
||||||
|
#
|
||||||
|
class swift::repo::trunk {
|
||||||
|
apt::ppa { 'ppa:swift-core/trunk': }
|
||||||
|
}
|
13
manifests/ringbuilder.pp
Normal file
13
manifests/ringbuilder.pp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#
|
||||||
|
# role for deploying
|
||||||
|
#
|
||||||
|
class swift::ringbuider(
|
||||||
|
|
||||||
|
) {
|
||||||
|
# search for all nodes that have class swift::storage
|
||||||
|
#
|
||||||
|
# determine what their swift drives are (how can I determine this?)
|
||||||
|
#exec {
|
||||||
|
# command =>
|
||||||
|
#}
|
||||||
|
}
|
8
manifests/ringbuilder/balance.pp
Normal file
8
manifests/ringbuilder/balance.pp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
define ringbuilder::rebalance() {
|
||||||
|
validate_re($name, '^object|contianer|account$')
|
||||||
|
exec { "rebalance_${name}":
|
||||||
|
command => "swift-ring-builder ${name}.builder rebalance",
|
||||||
|
path => ['/usr/bin'],
|
||||||
|
refreshonly => true,
|
||||||
|
}
|
||||||
|
}
|
86
manifests/storage.pp
Normal file
86
manifests/storage.pp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#
|
||||||
|
# class for building out a storage node
|
||||||
|
#
|
||||||
|
class swift::storage(
|
||||||
|
$package_ensure = 'present',
|
||||||
|
# TODO - should this default to 0.0.0.0?
|
||||||
|
$storage_local_net_ip = '127.0.0.1'
|
||||||
|
) inherits swift {
|
||||||
|
|
||||||
|
|
||||||
|
class{ 'rsync::server':
|
||||||
|
use_xinetd => false,
|
||||||
|
address => $storage_local_net_ip,
|
||||||
|
}
|
||||||
|
|
||||||
|
Service {
|
||||||
|
ensure => running,
|
||||||
|
enable => true,
|
||||||
|
hasstatus => true,
|
||||||
|
subscribe => Service['rsync'],
|
||||||
|
}
|
||||||
|
|
||||||
|
File {
|
||||||
|
owner => 'swift',
|
||||||
|
group => 'swift',
|
||||||
|
}
|
||||||
|
|
||||||
|
# package dependencies
|
||||||
|
package { ['xfsprogs', 'parted']:
|
||||||
|
ensure => 'present'
|
||||||
|
}
|
||||||
|
|
||||||
|
package { 'swift-account':
|
||||||
|
ensure => $package_ensure,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/account-server.conf':
|
||||||
|
ensure => present,
|
||||||
|
mode => 0660,
|
||||||
|
content => template('swift/account-server.conf.erb')
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/account-server/':
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
|
||||||
|
service { 'swift-account':
|
||||||
|
provider => 'upstart',
|
||||||
|
}
|
||||||
|
|
||||||
|
package { 'swift-container':
|
||||||
|
ensure => $package_ensure,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/container-server.conf':
|
||||||
|
ensure => present,
|
||||||
|
mode => 0660,
|
||||||
|
content => template('swift/container-server.conf.erb')
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/container-server/':
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
|
||||||
|
service { 'swift-container':
|
||||||
|
provider => 'upstart',
|
||||||
|
}
|
||||||
|
|
||||||
|
package { 'swift-object':
|
||||||
|
ensure => $package_ensure,
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/object-server.conf':
|
||||||
|
ensure => present,
|
||||||
|
mode => 0660,
|
||||||
|
content => template('swift/object-server.conf.erb')
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/etc/swift/object-server/':
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
|
||||||
|
service { 'swift-object':
|
||||||
|
provider => 'upstart',
|
||||||
|
}
|
||||||
|
}
|
44
manifests/storage/device.pp
Normal file
44
manifests/storage/device.pp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# I am not sure if this is the right name
|
||||||
|
# - should it be device?
|
||||||
|
#
|
||||||
|
# name - is going to be port
|
||||||
|
define swift::storage::device(
|
||||||
|
$type,
|
||||||
|
$devices = '/srv/node',
|
||||||
|
$owner = 'swift',
|
||||||
|
$group = 'swift',
|
||||||
|
$max_connections = 25,
|
||||||
|
$storage_local_net_ip = '127.0.0.1'
|
||||||
|
) {
|
||||||
|
|
||||||
|
validate_re($name, '^\d+$')
|
||||||
|
validate_re($type, '^object|container|account$')
|
||||||
|
# TODO - validate that name is an integer
|
||||||
|
|
||||||
|
# This makes me think that perhaps the rsync class
|
||||||
|
# should be split into install and config
|
||||||
|
#
|
||||||
|
Swift::Storage::Device[$name] ~> Service['rsync']
|
||||||
|
|
||||||
|
$bind_port = $name
|
||||||
|
|
||||||
|
Rsync::Server::Module {
|
||||||
|
uid => $owner,
|
||||||
|
gid => $group,
|
||||||
|
max_connections => $max_connections,
|
||||||
|
read_only => false,
|
||||||
|
}
|
||||||
|
|
||||||
|
rsync::server::module { "${type}${name}":
|
||||||
|
path => $devices,
|
||||||
|
lock_file => "/var/lock/${type}${name}.lock"
|
||||||
|
}
|
||||||
|
|
||||||
|
file { "/etc/swift/${type}-server/${name}.conf":
|
||||||
|
content => template("swift/${type}-server.conf.erb"),
|
||||||
|
owner => $owner,
|
||||||
|
group => $group,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
50
manifests/storage/loopback.pp
Normal file
50
manifests/storage/loopback.pp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# follow the instructions for creating a loopback device
|
||||||
|
# for storage from: http://swift.openstack.org/development_saio.html
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# creates a managed loopback interface
|
||||||
|
# - creates a file
|
||||||
|
# - formats the file to be an xfs device and mounts it as a loopback device at /srv/node/$name
|
||||||
|
# - sets up each mount point as a swift endpoint
|
||||||
|
define swift::storage::loopback(
|
||||||
|
$base_dir = '/srv/loopback-device',
|
||||||
|
$mnt_base_dir = '/srv/node',
|
||||||
|
$byte_size = '1024',
|
||||||
|
$seek = '25000',
|
||||||
|
$storage_local_net_ip = '127.0.0.1'
|
||||||
|
) {
|
||||||
|
|
||||||
|
if(!defined(File[$base_dir])) {
|
||||||
|
file { $base_dir:
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!defined(File[$mnt_base_dir])) {
|
||||||
|
file { $mnt_base_dir:
|
||||||
|
owner => 'swift',
|
||||||
|
group => 'swift',
|
||||||
|
ensure => directory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exec { "create_partition-${name}":
|
||||||
|
command => "dd if=/dev/zero of=${base_dir}/${name} bs=${byte_size} count=0 seek=${seek}",
|
||||||
|
path => ['/usr/bin/', '/bin'],
|
||||||
|
unless => "test -f ${base_dir}/${name}",
|
||||||
|
require => File[$base_dir],
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::xfs { $name:
|
||||||
|
device => "${base_dir}/${name}",
|
||||||
|
mnt_base_dir => $mnt_base_dir,
|
||||||
|
byte_size => $byte_size,
|
||||||
|
subscribe => Exec["create_partition-${name}"],
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::node { $name:
|
||||||
|
mnt_base_dir => $mnt_base_dir,
|
||||||
|
storage_local_net_ip => $storage_local_net_ip,
|
||||||
|
require => Swift::Storage::Xfs[$name]
|
||||||
|
}
|
||||||
|
}
|
43
manifests/storage/mount.pp
Normal file
43
manifests/storage/mount.pp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#
|
||||||
|
# Usage
|
||||||
|
# swift::storage::mount
|
||||||
|
#
|
||||||
|
#
|
||||||
|
define swift::storage::mount(
|
||||||
|
$device,
|
||||||
|
$mnt_base_dir = '/srv/node',
|
||||||
|
) {
|
||||||
|
|
||||||
|
# the directory that represents the mount point
|
||||||
|
# needs to exist
|
||||||
|
file { "${mnt_base_dir}/${name}":
|
||||||
|
ensure => directory,
|
||||||
|
owner => 'swift',
|
||||||
|
group => 'swift',
|
||||||
|
}
|
||||||
|
|
||||||
|
mount { "${mnt_base_dir}/${name}":
|
||||||
|
ensure => present,
|
||||||
|
device => $device,
|
||||||
|
fstype => 'xfs',
|
||||||
|
options => 'loop,noatime,nodiratime,nobarrier,logbufs=8',
|
||||||
|
require => File["${mnt_base_dir}/${name}"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# double checks to make sure that things are mounted
|
||||||
|
exec { "mount_${name}":
|
||||||
|
command => "mount ${mnt_base_dir}/${name}",
|
||||||
|
path => ['/bin'],
|
||||||
|
require => Mount["${mnt_base_dir}/${name}"],
|
||||||
|
unless => "grep ${mnt_base_dir}/${name} /etc/mtab",
|
||||||
|
# TODO - this needs to be removed when I am done testing
|
||||||
|
logoutput => true,
|
||||||
|
}
|
||||||
|
|
||||||
|
exec { "fix_mount_permissions_${name}":
|
||||||
|
command => "chown -R swift:swift ${mnt_base_dir}/${name}",
|
||||||
|
path => ['/usr/sbin', '/bin'],
|
||||||
|
subscribe => Exec["mount_${name}"],
|
||||||
|
refreshonly => true,
|
||||||
|
}
|
||||||
|
}
|
28
manifests/storage/node.pp
Normal file
28
manifests/storage/node.pp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
define swift::storage::node(
|
||||||
|
$mnt_base_dir,
|
||||||
|
$owner = 'swift',
|
||||||
|
$group = 'swift',
|
||||||
|
$max_connections = 25,
|
||||||
|
$storage_local_net_ip = '127.0.0.1'
|
||||||
|
) {
|
||||||
|
|
||||||
|
Swift::Storage::Device {
|
||||||
|
devices => $mnt_base_dir,
|
||||||
|
owner => $owner,
|
||||||
|
group => $group,
|
||||||
|
max_connections => $max_connections,
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::device { "60${name}0":
|
||||||
|
type => 'object',
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::device { "60${name}1":
|
||||||
|
type => 'container',
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::device { "60${name}2":
|
||||||
|
type => 'account',
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
manifests/storage/xfs.pp
Normal file
34
manifests/storage/xfs.pp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# follow the instructions for creating a loopback device
|
||||||
|
# for storage from: http://swift.openstack.org/development_saio.html
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# this define needs to be sent a refresh signal to do anything
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# [*title*]
|
||||||
|
#
|
||||||
|
# [*byte_size*] Byte size to use for every inode in the created filesystem.
|
||||||
|
# It is recommened to use 1024 to ensure that the metadata can fit in a single inode.
|
||||||
|
define swift::storage::xfs(
|
||||||
|
$device,
|
||||||
|
$byte_size = '1024',
|
||||||
|
$mnt_base_dir = '/srv/node'
|
||||||
|
) {
|
||||||
|
|
||||||
|
# does this have to be refreshonly?
|
||||||
|
# how can I know if this drive has been formatted?
|
||||||
|
exec { "mkfs-${name}":
|
||||||
|
command => "mkfs.xfs -i size=${byte_size} ${device}",
|
||||||
|
path => ['/sbin/'],
|
||||||
|
refreshonly => true,
|
||||||
|
require => Package['xfsprogs'],
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::storage::mount { $name:
|
||||||
|
device => $device,
|
||||||
|
mnt_base_dir => $mount_base_dir,
|
||||||
|
subscribe => Exec["mkfs-${name}"]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
spec/classes/.swift_storage_spec.rb.swp
Normal file
BIN
spec/classes/.swift_storage_spec.rb.swp
Normal file
Binary file not shown.
57
spec/classes/swift_storage_spec.rb
Normal file
57
spec/classes/swift_storage_spec.rb
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'swift::storage' do
|
||||||
|
|
||||||
|
let :pre_condition do
|
||||||
|
"class { 'swift': swift_hash_suffix => 'changeme' }
|
||||||
|
include ssh::server::install
|
||||||
|
"
|
||||||
|
end
|
||||||
|
|
||||||
|
let :default_params do
|
||||||
|
{
|
||||||
|
:package_ensure => 'present'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
[{},
|
||||||
|
{
|
||||||
|
:package_ensure => 'latest'
|
||||||
|
}
|
||||||
|
].each do |param_set|
|
||||||
|
|
||||||
|
describe "when #{param_set == {} ? "using default" : "specifying"} class parameters" do
|
||||||
|
let :param_hash do
|
||||||
|
default_params.merge(param_set)
|
||||||
|
end
|
||||||
|
|
||||||
|
let :params do
|
||||||
|
param_set
|
||||||
|
end
|
||||||
|
|
||||||
|
['xfsprogs', 'parted', 'rsync'].each do |present_package|
|
||||||
|
it { should contain_package(present_package).with_ensure('present') }
|
||||||
|
end
|
||||||
|
#it 'should compile the template based on the class parameters' do
|
||||||
|
# content = param_value(subject, 'file', '/etc/glance/glance-api.conf', 'content')
|
||||||
|
# expected_lines = [
|
||||||
|
# "verbose = #{param_hash[:log_verbose]}",
|
||||||
|
# "debug = #{param_hash[:log_debug]}",
|
||||||
|
# "default_store = #{param_hash[:default_store]}",
|
||||||
|
# "bind_host = #{param_hash[:bind_host]}",
|
||||||
|
# "bind_port = #{param_hash[:bind_port]}",
|
||||||
|
# "registry_host = #{param_hash[:registry_host]}",
|
||||||
|
# "registry_port = #{param_hash[:registry_port]}",
|
||||||
|
# "log_file = #{param_hash[:log_file]}",
|
||||||
|
# "filesystem_store_datadir = #{param_hash[:filesystem_store_datadir]}",
|
||||||
|
# "swift_store_auth_address = #{param_hash[:swift_store_auth_address]}",
|
||||||
|
# "swift_store_user = #{param_hash[:swift_store_user]}",
|
||||||
|
# "swift_store_key = #{param_hash[:swift_store_key]}",
|
||||||
|
# "swift_store_container = #{param_hash[:swift_store_container]}",
|
||||||
|
# "swift_store_create_container_on_put = #{param_hash[:swift_store_create_container_on_put]}"
|
||||||
|
# ]
|
||||||
|
# (content.split("\n") & expected_lines).should == expected_lines
|
||||||
|
#end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
6
spec/spec.opts
Normal file
6
spec/spec.opts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
--format
|
||||||
|
s
|
||||||
|
--colour
|
||||||
|
--loadby
|
||||||
|
mtime
|
||||||
|
--backtrace
|
11
spec/spec_helper.rb
Normal file
11
spec/spec_helper.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
require 'puppet'
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rspec-puppet'
|
||||||
|
|
||||||
|
def param_value(subject, type, title, param)
|
||||||
|
subject.resource(type, title).send(:parameters)[param.to_sym]
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |c|
|
||||||
|
c.module_path = File.join(File.dirname(__FILE__), '../../')
|
||||||
|
end
|
25
templates/account-server.conf.erb
Normal file
25
templates/account-server.conf.erb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
<% if scope.lookupvar('devices') != :undefined -%>
|
||||||
|
devices = <%= devices %>
|
||||||
|
<% end -%>
|
||||||
|
bind_ip = <%= storage_local_net_ip %>
|
||||||
|
<% if scope.lookupvar('bind_port') != :undefined -%>
|
||||||
|
bind_port = <%= bind_port %>
|
||||||
|
<% end -%>
|
||||||
|
mount_check = false
|
||||||
|
user = swift
|
||||||
|
log_facility = LOG_LOCAL2
|
||||||
|
workers = 2
|
||||||
|
|
||||||
|
[pipeline:main]
|
||||||
|
pipeline = account-server
|
||||||
|
|
||||||
|
[app:account-server]
|
||||||
|
use = egg:swift#account
|
||||||
|
|
||||||
|
[account-replicator]
|
||||||
|
vm_test_mode = yes
|
||||||
|
|
||||||
|
[account-auditor]
|
||||||
|
|
||||||
|
[account-reaper]
|
27
templates/container-server.conf.erb
Normal file
27
templates/container-server.conf.erb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
<% if scope.lookupvar('devices') != :undefined -%>
|
||||||
|
devices = <%= devices %>
|
||||||
|
<% end -%>
|
||||||
|
bind_ip = <%= storage_local_net_ip %>
|
||||||
|
<% if scope.lookupvar('bind_port') != :undefined -%>
|
||||||
|
bind_port = <%= bind_port %>
|
||||||
|
<% end -%>
|
||||||
|
mount_check = false
|
||||||
|
user = swift
|
||||||
|
log_facility = LOG_LOCAL2
|
||||||
|
workers = 2
|
||||||
|
|
||||||
|
[pipeline:main]
|
||||||
|
pipeline = container-server
|
||||||
|
|
||||||
|
[app:container-server]
|
||||||
|
use = egg:swift#container
|
||||||
|
|
||||||
|
[container-replicator]
|
||||||
|
vm_test_mode = yes
|
||||||
|
|
||||||
|
[container-updater]
|
||||||
|
|
||||||
|
[container-auditor]
|
||||||
|
|
||||||
|
[container-sync]
|
25
templates/object-server.conf.erb
Normal file
25
templates/object-server.conf.erb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
<% if scope.lookupvar('devices') != :undefined -%>
|
||||||
|
devices = <%= devices %>
|
||||||
|
<% end -%>
|
||||||
|
bind_ip = <%= storage_local_net_ip %>
|
||||||
|
<% if scope.lookupvar('bind_port') != :undefined -%>
|
||||||
|
bind_port = <%= bind_port %>
|
||||||
|
<% end -%>
|
||||||
|
mount_check = false
|
||||||
|
user = swift
|
||||||
|
log_facility = LOG_LOCAL2
|
||||||
|
workers = 2
|
||||||
|
|
||||||
|
[pipeline:main]
|
||||||
|
pipeline = object-server
|
||||||
|
|
||||||
|
[app:object-server]
|
||||||
|
use = egg:swift#object
|
||||||
|
|
||||||
|
[object-replicator]
|
||||||
|
vm_test_mode = yes
|
||||||
|
|
||||||
|
[object-updater]
|
||||||
|
|
||||||
|
[object-auditor]
|
40
templates/proxy-server.conf.erb
Normal file
40
templates/proxy-server.conf.erb
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# This file is managed by puppet. Do not edit
|
||||||
|
#
|
||||||
|
[DEFAULT]
|
||||||
|
#cert_file = /etc/swift/cert.crt
|
||||||
|
#key_file = /etc/swift/cert.key
|
||||||
|
bind_port = 8080
|
||||||
|
workers = 8
|
||||||
|
user = swift
|
||||||
|
|
||||||
|
[pipeline:main]
|
||||||
|
# ratelimit?
|
||||||
|
pipeline = healthcheck cache <%= auth_type %> proxy-server
|
||||||
|
|
||||||
|
[app:proxy-server]
|
||||||
|
use = egg:swift#proxy
|
||||||
|
allow_account_management = <%= allow_account_management %>
|
||||||
|
account_autocreate = <%= account_autocreate %>
|
||||||
|
|
||||||
|
<% if auth_type == 'swauth' %>
|
||||||
|
[filter:swauth]
|
||||||
|
use = egg:swauth#swauth
|
||||||
|
# this line is not in the install docs?
|
||||||
|
default_swift_cluster = local#<%= swauth_endpoint %>
|
||||||
|
super_admin_key = <%= swauth_super_admin_key %>
|
||||||
|
<% elsif auth_type == 'tempauth' %>
|
||||||
|
[filter:tempauth]
|
||||||
|
use = egg:swift#tempauth
|
||||||
|
user_admin_admin = admin .admin .reseller_admin
|
||||||
|
user_test_tester = testing .admin
|
||||||
|
user_test2_tester2 = testing2 .admin
|
||||||
|
user_test_tester3 = testing3
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
[filter:healthcheck]
|
||||||
|
use = egg:swift#healthcheck
|
||||||
|
|
||||||
|
[filter:cache]
|
||||||
|
use = egg:swift#memcache
|
||||||
|
# multi-proxy config not supported
|
||||||
|
memcache_servers = <%= proxy_local_net_ip %>:<%= proxy_port %>
|
25
templates/rsyncd.conf.erb
Normal file
25
templates/rsyncd.conf.erb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
uid = swift
|
||||||
|
gid = swift
|
||||||
|
|
||||||
|
# this should really be bound on an internal-only network
|
||||||
|
log file = /var/log/rsyncd.log
|
||||||
|
pid file = /var/run/rsyncd.pid
|
||||||
|
address = 0.0.0.0
|
||||||
|
|
||||||
|
[account]
|
||||||
|
max connections = 2
|
||||||
|
path = /srv/node/
|
||||||
|
read only = false
|
||||||
|
lock file = /var/lock/account.lock
|
||||||
|
|
||||||
|
[container]
|
||||||
|
max connections = 2
|
||||||
|
path = /srv/node/
|
||||||
|
read only = false
|
||||||
|
lock file = /var/lock/container.lock
|
||||||
|
|
||||||
|
[object]
|
||||||
|
max connections = 2
|
||||||
|
path = /srv/node/
|
||||||
|
read only = false
|
||||||
|
lock file = /var/lock/object.lock
|
2
templates/swift.conf.erb
Normal file
2
templates/swift.conf.erb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[swift-hash]
|
||||||
|
swift_hash_path_suffix = <%= swift_hash_suffix %>
|
Loading…
Reference in New Issue
Block a user