pipette 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +18 -0
- data/LICENSE +20 -0
- data/README +0 -0
- data/README.rdoc +17 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/bin/pipette +75 -0
- data/lib/pipette/commands.rb +93 -0
- data/lib/pipette/ec2.rb +36 -0
- data/lib/pipette/lvm.rb +49 -0
- data/lib/pipette/md.rb +16 -0
- data/lib/pipette/util.rb +76 -0
- data/lib/pipette/xfs.rb +22 -0
- data/lib/pipette.rb +24 -0
- data/spec/pipette_spec.rb +7 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- metadata +146 -0
data/.document
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
right_aws (2.0.0)
|
5
|
+
right_http_connection (>= 1.2.1)
|
6
|
+
right_http_connection (1.2.4)
|
7
|
+
rspec (1.3.0)
|
8
|
+
trollop (1.16.2)
|
9
|
+
yard (0.5.8)
|
10
|
+
|
11
|
+
PLATFORMS
|
12
|
+
ruby
|
13
|
+
|
14
|
+
DEPENDENCIES
|
15
|
+
right_aws
|
16
|
+
rspec
|
17
|
+
trollop
|
18
|
+
yard
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Paul Sadauskas
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= pipette
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Paul Sadauskas. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "pipette"
|
8
|
+
gem.summary = %Q{pipette is a tool for managing volumes}
|
9
|
+
gem.description = %Q{Create, grow, and remove ebs+md+lvm volumes and disks}
|
10
|
+
gem.email = "psadauskas@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/mongomachine/pipette"
|
12
|
+
gem.authors = ["Paul Sadauskas"]
|
13
|
+
|
14
|
+
gem.add_dependency "trollop"
|
15
|
+
gem.add_dependency "right_aws"
|
16
|
+
|
17
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
18
|
+
gem.add_development_dependency "yard", ">= 0"
|
19
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
|
+
end
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'spec/rake/spectask'
|
27
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
28
|
+
spec.libs << 'lib' << 'spec'
|
29
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
30
|
+
end
|
31
|
+
|
32
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
33
|
+
spec.libs << 'lib' << 'spec'
|
34
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
35
|
+
spec.rcov = true
|
36
|
+
end
|
37
|
+
|
38
|
+
task :spec => :check_dependencies
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
rescue LoadError
|
42
|
+
task :spec do
|
43
|
+
abort "RSpec is not available."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
require 'yard'
|
49
|
+
YARD::Rake::YardocTask.new
|
50
|
+
rescue LoadError
|
51
|
+
task :yardoc do
|
52
|
+
abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
|
53
|
+
end
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/pipette
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'trollop'
|
5
|
+
|
6
|
+
SUB_COMMANDS = %w[ init append add grow remove ]
|
7
|
+
|
8
|
+
opts = Trollop::options do
|
9
|
+
banner <<-EOS
|
10
|
+
This script will manage mirrored EBS volumes and lvm volume groups.
|
11
|
+
|
12
|
+
Usage:
|
13
|
+
pipette [global options] subcommand [options]
|
14
|
+
|
15
|
+
Where subcommand is one of #{SUB_COMMANDS.inspect}
|
16
|
+
|
17
|
+
Global Options:
|
18
|
+
EOS
|
19
|
+
opt :access_key, "AWS Access Key", :short => "-a", :default => ENV['ACCESS_KEY']
|
20
|
+
opt :secret_access_key, "AWS Secret Access Key", :short => "-c", :default => ENV['SECRET_ACCESS_KEY']
|
21
|
+
stop_on SUB_COMMANDS
|
22
|
+
end
|
23
|
+
|
24
|
+
cmd = ARGV.shift
|
25
|
+
cmd_opts = case cmd
|
26
|
+
when "init"
|
27
|
+
Trollop::options do
|
28
|
+
banner "Create an initial volume group of EBS mirrored volumes"
|
29
|
+
opt :name , "Name of volume group to create" , :short => "-n", :required => true, :type => :string
|
30
|
+
opt :size , "Size of initial volume in GB" , :short => "-s", :required => true, :type => :int
|
31
|
+
opt :ebs_per_mirror, "Number of EBS volumes to put in each mirrored disk" , :default => 2 , :type => :int
|
32
|
+
opt :num_mirrors , "Number of mirrors to create; will be spanned by the volume group", :default => 2 , :type => :int
|
33
|
+
end
|
34
|
+
when "append"
|
35
|
+
Trollop::options do
|
36
|
+
banner "Add another set of mirrored EBS volumes to the volume group"
|
37
|
+
opt :name , "Name of volume group to append to" , :short => "-n", :required => true, :type => :string
|
38
|
+
opt :size , "Size of initial volume in GB" , :short => "-s", :required => true, :type => :int
|
39
|
+
opt :ebs_per_mirror, "Number of EBS volumes to put in each mirrored disk" , :default => 2 , :type => :int
|
40
|
+
opt :num_mirrors , "Number of mirrors to create; will be spanned by the volume group", :default => 1 , :type => :int
|
41
|
+
end
|
42
|
+
when "add"
|
43
|
+
Trollop::options do
|
44
|
+
banner "Create a new logical volume in the volume group"
|
45
|
+
opt :name , "Name of new logical volume" , :short => "-n", :required => true, :type => :string
|
46
|
+
opt :volume, "Name of volume group to use" , :short => "-v", :required => true, :type => :string
|
47
|
+
opt :size , "Size of new logical volume", :short => "-s", :required => true, :type => :int
|
48
|
+
end
|
49
|
+
when "grow"
|
50
|
+
Trollop::options do
|
51
|
+
banner "Increase the size of a logical volume"
|
52
|
+
opt :name , "Name of logical volume" , :short => "-n", :required => true, :type => :string
|
53
|
+
opt :volume, "Name of volume group to use" , :short => "-v", :required => true, :type => :string
|
54
|
+
opt :size , "Size to increase logical volume to or '+n' to increase size by nGB", :short => "-s", :required => true, :type => :string
|
55
|
+
end
|
56
|
+
when "remove"
|
57
|
+
Trollop::options do
|
58
|
+
banner "Remove a logical volume"
|
59
|
+
opt :name , "Name of logical volume" , :short => "-n", :required => true, :type => :string
|
60
|
+
opt :volume, "Name of volume group to use", :short => "-v", :required => true, :type => :string
|
61
|
+
end
|
62
|
+
else
|
63
|
+
Trollop::die "unknown subcommand #{cmd.inspect}"
|
64
|
+
end
|
65
|
+
|
66
|
+
begin
|
67
|
+
require 'pipette'
|
68
|
+
rescue LoadError => ex
|
69
|
+
# Not in load path
|
70
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'pipette')
|
71
|
+
end
|
72
|
+
|
73
|
+
Pipette.new(opts).send(cmd, cmd_opts)
|
74
|
+
|
75
|
+
# vim: ft=ruby
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
class Pipette
|
3
|
+
module Commands
|
4
|
+
|
5
|
+
# cmd_opts:
|
6
|
+
#
|
7
|
+
# size: Size of each volume, in GB
|
8
|
+
# name: Name of the volume group to create
|
9
|
+
# ebs_per_mirror: Number of EBS volumes to put in each mirrored disk. Default 2.
|
10
|
+
# num_mirrors: Number of mirrors to create, to be spanned by the volume group. Default 2.
|
11
|
+
def init(cmd_opts)
|
12
|
+
raise "No volume group name specified" unless cmd_opts[:name]
|
13
|
+
raise "No EBS volume size specified" unless cmd_opts[:size]
|
14
|
+
|
15
|
+
md_devs = create_mirrors(cmd_opts[:size],
|
16
|
+
cmd_opts[:num_mirrors],
|
17
|
+
cmd_opts[:ebs_per_mirror])
|
18
|
+
|
19
|
+
|
20
|
+
vg_create cmd_opts[:name], md_devs
|
21
|
+
end
|
22
|
+
|
23
|
+
def append(cmd_opts)
|
24
|
+
raise "No volume group name specified" unless cmd_opts[:name]
|
25
|
+
raise "No EBS volume size specified" unless cmd_opts[:size]
|
26
|
+
|
27
|
+
md_devs = create_mirrors(cmd_opts[:size],
|
28
|
+
cmd_opts[:num_mirrors],
|
29
|
+
cmd_opts[:ebs_per_mirror])
|
30
|
+
|
31
|
+
vg_extend cmd_opts[:name], md_devs
|
32
|
+
end
|
33
|
+
|
34
|
+
def add(cmd_opts)
|
35
|
+
raise "No logical volume name specified" unless cmd_opts[:name]
|
36
|
+
raise "No logical volume size specified" unless cmd_opts[:size]
|
37
|
+
raise "No volume group name specified" unless cmd_opts[:volume]
|
38
|
+
|
39
|
+
dev = lv_create(cmd_opts[:name], cmd_opts[:volume], cmd_opts[:size])
|
40
|
+
format(dev)
|
41
|
+
mount(dev, "/data/#{cmd_opts[:name]}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def grow(cmd_opts)
|
45
|
+
raise "No logical volume name specified" unless cmd_opts[:name]
|
46
|
+
raise "No logical volume size specified" unless cmd_opts[:size]
|
47
|
+
raise "No volume group name specified" unless cmd_opts[:volume]
|
48
|
+
|
49
|
+
dev = lv_dev(cmd_opts[:volume], cmd_opts[:name])
|
50
|
+
lv_extend(dev, cmd_opts[:size])
|
51
|
+
growfs(dev)
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove(cmd_opts)
|
55
|
+
raise "No logical volume name specified" unless cmd_opts[:name]
|
56
|
+
raise "No volume group name specified" unless cmd_opts[:volume]
|
57
|
+
|
58
|
+
dev = lv_dev(cmd_opts[:volume], cmd_opts[:name])
|
59
|
+
umount(dev)
|
60
|
+
lv_remove(dev)
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
def create_mirrors(size, num_mirrors = 2, num_disks = 2)
|
66
|
+
md_devs = []
|
67
|
+
num_mirrors.times do
|
68
|
+
volumes = []
|
69
|
+
num_disks.times do
|
70
|
+
volumes << create_volume(size)
|
71
|
+
end
|
72
|
+
|
73
|
+
devices = []
|
74
|
+
volumes.each do |v_id|
|
75
|
+
mp = next_avail_disk
|
76
|
+
mount_volume v_id, mp
|
77
|
+
devices << mp
|
78
|
+
end
|
79
|
+
|
80
|
+
wait_for devices
|
81
|
+
|
82
|
+
md_dev = next_md
|
83
|
+
create_md_mirror md_dev, *devices
|
84
|
+
|
85
|
+
pv_create md_dev
|
86
|
+
md_devs << md_dev
|
87
|
+
end
|
88
|
+
|
89
|
+
md_devs
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
data/lib/pipette/ec2.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
class Pipette
|
4
|
+
module Ec2
|
5
|
+
|
6
|
+
def ec2
|
7
|
+
@ec2 ||= RightAws::Ec2.new(opts[:access_key], opts[:secret_access_key])
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_volume(size)
|
11
|
+
say_with_time "Creating new volume of size #{size}G" do
|
12
|
+
res = ec2.create_volume(nil, size, zone)
|
13
|
+
res[:aws_id]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def mount_volume(volume_id, mount_point)
|
18
|
+
say_with_time "Mounting #{volume_id} at #{mount_point}" do
|
19
|
+
res = ec2.attach_volume(volume_id, instance_id, mount_point)
|
20
|
+
res[:aws_device]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def zone
|
25
|
+
@zone ||= meta("placement/availability-zone")
|
26
|
+
end
|
27
|
+
|
28
|
+
def instance_id
|
29
|
+
@instance_id ||= meta("instance-id")
|
30
|
+
end
|
31
|
+
|
32
|
+
def meta(path)
|
33
|
+
open("http://169.254.169.254/latest/meta-data/#{path}").read.strip
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/pipette/lvm.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
class Pipette
|
3
|
+
module Lvm
|
4
|
+
|
5
|
+
def pv_create(device)
|
6
|
+
run_command "pvcreate", device
|
7
|
+
end
|
8
|
+
|
9
|
+
def vg_create(name, *devices)
|
10
|
+
run_command "vgcreate",
|
11
|
+
"--physicalextentsize 16M",
|
12
|
+
name,
|
13
|
+
*devices
|
14
|
+
end
|
15
|
+
|
16
|
+
def vg_extend(name, *devices)
|
17
|
+
run_command "vgextend",
|
18
|
+
name,
|
19
|
+
*devices
|
20
|
+
end
|
21
|
+
|
22
|
+
def lv_create(name, vg, size)
|
23
|
+
run_command "lvcreate",
|
24
|
+
"--size #{size}G",
|
25
|
+
"--name #{name}",
|
26
|
+
vg
|
27
|
+
|
28
|
+
lv_dev(vg, name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def lv_extend(device, size)
|
32
|
+
run_command "lvextend",
|
33
|
+
"--size #{size}G",
|
34
|
+
device
|
35
|
+
end
|
36
|
+
|
37
|
+
def lv_remove(device)
|
38
|
+
run_command "lvremove", "--force", device
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def lv_dev(vg, name)
|
44
|
+
"/dev/#{vg}/#{name}"
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
data/lib/pipette/md.rb
ADDED
data/lib/pipette/util.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
class Pipette
|
3
|
+
module Util
|
4
|
+
|
5
|
+
def run_command(cmd, *args)
|
6
|
+
args.unshift(cmd)
|
7
|
+
|
8
|
+
command = args.flatten.join(' ')
|
9
|
+
|
10
|
+
say_with_time command do
|
11
|
+
`#{command}`
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def next_avail_disk
|
16
|
+
@last_disk ||= Dir["/dev/sd[d-p]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}"].sort { |a,b|
|
17
|
+
disk_parts(a) <=> disk_parts(b)
|
18
|
+
}.last
|
19
|
+
|
20
|
+
disk, part = disk_parts(@last_disk)
|
21
|
+
|
22
|
+
if disk
|
23
|
+
if part.to_i >= 15
|
24
|
+
disk = disk.succ
|
25
|
+
part = 1
|
26
|
+
else
|
27
|
+
part += 1
|
28
|
+
end
|
29
|
+
else
|
30
|
+
disk, part = "d", "1"
|
31
|
+
end
|
32
|
+
|
33
|
+
@last_disk = "/dev/sd#{disk}#{part}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def next_md
|
37
|
+
md = Dir["/dev/md[0-9]*"].sort.last
|
38
|
+
if md && match = md.match(%r{/dev/md([\d+])})
|
39
|
+
i = match[1].to_i + 1
|
40
|
+
else
|
41
|
+
i = 0
|
42
|
+
end
|
43
|
+
"/dev/md#{i}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def disk_parts(dev)
|
47
|
+
if dev && match = dev.match(%r{/dev/sd([d-p])([0-1][0-9]|[0-9])})
|
48
|
+
disk, part = match[1], match[2].to_i
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def say_with_time(msg = "", &block)
|
55
|
+
@depth ||= 0
|
56
|
+
@depth += 1
|
57
|
+
indent = ' ' * @depth
|
58
|
+
puts "#{indent}#{msg}"
|
59
|
+
t = Time.now
|
60
|
+
res = yield
|
61
|
+
puts "#{indent}-> %0.4f" % (Time.now - t)
|
62
|
+
@depth -= 1
|
63
|
+
res
|
64
|
+
end
|
65
|
+
|
66
|
+
def wait_for(*paths)
|
67
|
+
paths.flatten.each do |path|
|
68
|
+
puts "Waiting for #{path} to appear..."
|
69
|
+
until File.exist?(path)
|
70
|
+
sleep 0.1
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
data/lib/pipette/xfs.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
class Pipette
|
3
|
+
module Xfs
|
4
|
+
|
5
|
+
def format(device)
|
6
|
+
run_command "mkfs.xfs", device
|
7
|
+
end
|
8
|
+
|
9
|
+
def mount(device, mountpoint)
|
10
|
+
FileUtils.mkdir_p(mountpoint)
|
11
|
+
run_command "mount", device, mountpoint
|
12
|
+
end
|
13
|
+
|
14
|
+
def growfs(device)
|
15
|
+
run_command "xfs_growfs", device
|
16
|
+
end
|
17
|
+
|
18
|
+
def umount(device)
|
19
|
+
run_command "umount", device
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/pipette.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'right_aws'
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
%w[ util ec2 md lvm xfs commands ].each do |file|
|
6
|
+
require File.join(dir, 'pipette', file)
|
7
|
+
end
|
8
|
+
|
9
|
+
class Pipette
|
10
|
+
include Util
|
11
|
+
include Ec2
|
12
|
+
include Md
|
13
|
+
include Lvm
|
14
|
+
include Xfs
|
15
|
+
include Commands
|
16
|
+
|
17
|
+
attr_reader :opts
|
18
|
+
|
19
|
+
def initialize(opts)
|
20
|
+
@opts = opts
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pipette
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Paul Sadauskas
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-18 00:00:00 -06:00
|
19
|
+
default_executable: pipette
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: trollop
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: right_aws
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 13
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 2
|
61
|
+
- 9
|
62
|
+
version: 1.2.9
|
63
|
+
type: :development
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: yard
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
type: :development
|
78
|
+
version_requirements: *id004
|
79
|
+
description: Create, grow, and remove ebs+md+lvm volumes and disks
|
80
|
+
email: psadauskas@gmail.com
|
81
|
+
executables:
|
82
|
+
- pipette
|
83
|
+
extensions: []
|
84
|
+
|
85
|
+
extra_rdoc_files:
|
86
|
+
- LICENSE
|
87
|
+
- README
|
88
|
+
- README.rdoc
|
89
|
+
files:
|
90
|
+
- .document
|
91
|
+
- .gitignore
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE
|
95
|
+
- README
|
96
|
+
- README.rdoc
|
97
|
+
- Rakefile
|
98
|
+
- VERSION
|
99
|
+
- bin/pipette
|
100
|
+
- lib/pipette.rb
|
101
|
+
- lib/pipette/commands.rb
|
102
|
+
- lib/pipette/ec2.rb
|
103
|
+
- lib/pipette/lvm.rb
|
104
|
+
- lib/pipette/md.rb
|
105
|
+
- lib/pipette/util.rb
|
106
|
+
- lib/pipette/xfs.rb
|
107
|
+
- spec/pipette_spec.rb
|
108
|
+
- spec/spec.opts
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
has_rdoc: true
|
111
|
+
homepage: http://github.com/mongomachine/pipette
|
112
|
+
licenses: []
|
113
|
+
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options:
|
116
|
+
- --charset=UTF-8
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
version: "0"
|
137
|
+
requirements: []
|
138
|
+
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 1.3.7
|
141
|
+
signing_key:
|
142
|
+
specification_version: 3
|
143
|
+
summary: pipette is a tool for managing volumes
|
144
|
+
test_files:
|
145
|
+
- spec/pipette_spec.rb
|
146
|
+
- spec/spec_helper.rb
|