frachtraum 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTNlZjE2YmIwY2NhMmFiNzYyNzA4MTYyNTJmNTRhN2E5YTFmNzRkNw==
5
+ data.tar.gz: !binary |-
6
+ NWY4N2NmYzQyZTM0MGExN2M1ZGZlMjYxODZiMDlmYmNjZTcxMTljMg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MTVjNzg3YzY0MmQ5ZWYzNDE1NzcxNDU2NGY1MWUxMWQxOTMzMjE1NTQ1YjE1
10
+ ZmEwYmNkNjQyZjYyZDA0YTY4N2I2MGM2YzliZjg2M2U0MmQzNmFmODBmYmQy
11
+ ZDQxMGYxMTM1ZDEyZDhhMGE3NmZmN2RkZjI5NmEwYTBlNDlmNjc=
12
+ data.tar.gz: !binary |-
13
+ NmE4NjFmZDhhNWNhNmUyZjFjMzFjYzMxYjlkNmQxNmU1OWQwNjY1ZjA4YTQx
14
+ ZDRkZjA4MWYxZmU0YWJlYzJmZGFlMDA2NTZkZjJlNzhkZTBmZGZhOGFlZmNj
15
+ MDdmOWI0ODkyZTQ1ZTVhMjgxZWE0YmU1MTU5MDA1M2Y3YWZkOTc=
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fsinv.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Maximilian Irro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # frachtraum
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/frachtraum.svg)](http://badge.fury.io/rb/frachtraum)
4
+
5
+ Oh this is really great. If I only took the time to tell you about it...
data/bin/frachtraum ADDED
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding : utf-8 -*-
3
+
4
+ require 'frachtraum'
5
+ require 'thor'
6
+ require 'highline/import'
7
+ require 'rainbow'
8
+
9
+ def prompt_password(prompt="Password: ")
10
+ HighLine.ask(prompt) { |q|
11
+ q.echo = false
12
+ # q.echo = "*"
13
+ }
14
+ end
15
+
16
+ class FrachtraumCLI < Thor
17
+
18
+ desc "attach [DEPOT]", "decrypt and mount depot(s)"
19
+ long_desc <<-LONGDESC
20
+ `frachtraum attach` will prompt you for a password.
21
+
22
+ The password is used to decrypt all depots specified
23
+ in #{Frachtraum::CONFIG_FILE}
24
+
25
+ You can optionally specify a single depot. In this case
26
+ only this depot will be decrypted and mounted.
27
+ LONGDESC
28
+ def attach(depot=nil)
29
+
30
+ password = prompt_password
31
+
32
+ Frachtraum.attach password, depot
33
+ end
34
+
35
+ # --------------
36
+
37
+ desc "capacity [OPTION]", "calculate storage capacity"
38
+ long_desc <<-LONGDESC
39
+ `frachtraum capacity` will output capacity...
40
+
41
+ lorem ipsum
42
+ LONGDESC
43
+ def capacity(option=nil)
44
+ c = Frachtraum.capacity
45
+
46
+ case option
47
+ when "smb", "samba"
48
+ puts "#{c[:total]/1000} #{c[:avail]/1000}"
49
+ else
50
+ puts ""
51
+ puts "Capacity:"
52
+ puts " Available: #{Frachtraum.pretty_SI_bytes(c[:avail])}"
53
+ puts " Used: #{Frachtraum.pretty_SI_bytes(c[:used])}"
54
+ puts " Total: #{Frachtraum.pretty_SI_bytes(c[:total])}"
55
+ puts ""
56
+ end
57
+ end
58
+
59
+ # --------------
60
+
61
+ desc "list", "list depots and/or timemachine targets"
62
+ long_desc <<-LONGDESC
63
+ lorem ipsum
64
+ LONGDESC
65
+ option :simple, :type => :boolean
66
+ def list(subset=nil)
67
+
68
+ list_width = 60 # character length of list
69
+
70
+ if subset == "depot" || subset == "depots" || subset.nil?
71
+ if options[:simple]
72
+ Frachtraum::DEPOTS.each{ |depot| puts depot }
73
+ else
74
+ puts "" # empty line
75
+ puts "Depots:"
76
+ puts "" # empty line
77
+ Frachtraum::DEPOTS.each{ |dataset|
78
+ status =
79
+ if Frachtraum.zfs_dataset_exists?(dataset)
80
+ Rainbow("attached").green
81
+ else
82
+ Rainbow("UNAVAILABLE").red
83
+ end
84
+ status = "[#{status}]".rjust(list_width-dataset.length)
85
+ puts " #{dataset}#{status}"
86
+ }
87
+ puts "" # empty line
88
+ end
89
+ end
90
+
91
+ if subset == "timemachine" || subset == "tm" || subset.nil?
92
+ if options[:simple]
93
+ Frachtraum::TIMEMACHINE_TARGETS.each{ |depot| puts depot }
94
+ else
95
+ puts "" unless subset.nil? # empty line
96
+ puts "Timemachine targets:"
97
+ puts "" # empty line
98
+ Frachtraum::TIMEMACHINE_TARGETS.each{ |dataset|
99
+ status =
100
+ if Frachtraum.zfs_dataset_exists?(dataset)
101
+ Rainbow("attached").green
102
+ else
103
+ Rainbow("UNAVAILABLE").red
104
+ end
105
+ status = "[#{status}]".rjust(list_width-dataset.length)
106
+ puts " #{dataset}#{status}"
107
+ }
108
+ puts "" # empty line
109
+ end
110
+ end
111
+ end
112
+
113
+ # --------------
114
+
115
+ desc "report", "lorem ipsum"
116
+ long_desc <<-LONGDESC
117
+ lorem ipsum
118
+ LONGDESC
119
+ def report()
120
+ # TODO
121
+ end
122
+
123
+ # --------------
124
+
125
+ desc "setupdisk", "setup a device as a new depot"
126
+ long_desc <<-LONGDESC
127
+ `frachtraum setup dev label` will setup...
128
+
129
+ lorem ispum
130
+ LONGDESC
131
+ options :compression => :string, :encryption => :string, :keylength => :integer, :mountpoint => :string
132
+ def setupdisk(dev,label)
133
+
134
+ compression = options[:compression] ? options[:compression] : Frachtraum::COMPRESSION
135
+ encryption = options[:encryption] ? options[:encryption] : Frachtraum::ENCRYPTION
136
+ keylength = options[:keylength] ? options[:keylength] : Frachtraum::KEYLENGTH
137
+ mountpoint = options[:mountpoint] ? options[:mountpoint] : Frachtraum::MOUNTPOINT
138
+
139
+ password1 = prompt_password("enter encryption password: ")
140
+ password2 = prompt_password("enter password again: ")
141
+ if password1.match(password2)
142
+ password = password1
143
+ else
144
+ abort "passwords not equal!"
145
+ end
146
+
147
+ puts ""
148
+ puts "Device: #{dev}"
149
+ puts "Label: #{label}"
150
+ puts "Compression: #{compression}"
151
+ puts "Encryption: #{encryption}"
152
+ puts "Keylength: #{keylength}"
153
+ puts "Mountpoint: #{mountpoint}"
154
+ puts ""
155
+ puts "ATTENTION! This is a destructive action. All data on the device will be"
156
+ puts "wiped. If you forget you password, you will not be able to access any"
157
+ puts "containing data any more."
158
+ puts ""
159
+
160
+ answer = HighLine.ask("Are you sure you want to continue? (type 'yes'): ") { |q| q.echo = true }
161
+
162
+ if answer.downcase.match("yes")
163
+ Frachtraum.setupdisk dev, label, password, compression, encryption, keylength, mountpoint
164
+ else
165
+ abort "ABORT -- device will not pe processed!"
166
+ end
167
+ end
168
+
169
+ # --------------
170
+
171
+ desc "sweep", "sweep the depots!"
172
+ long_desc <<-LONGDESC
173
+ `frachtraum sweep` will ...
174
+
175
+ lorem ipsum
176
+ LONGDESC
177
+ def sweep()
178
+ # TODO
179
+ Frachtraum::DEPOTS.each do |depot|
180
+
181
+
182
+ end
183
+ end
184
+
185
+ # --------------
186
+
187
+ desc "test", "test system for compatibility"
188
+ long_desc <<-LONGDESC
189
+ `frachtraum test` will test...
190
+
191
+ lorem ipsum
192
+ LONGDESC
193
+ def test()
194
+ Frachtraum.run_system_test
195
+ end
196
+
197
+ end
198
+
199
+ FrachtraumCLI.start(ARGV)
@@ -0,0 +1,10 @@
1
+ # Example Config
2
+ #
3
+ # Copy it to ~/.frachtraum.conf and edit it to your own needs
4
+ #
5
+ compression = lz4
6
+ depots = depot1,depot2,depot3
7
+ encryption = AES-XTS
8
+ keylength = 4096
9
+ mountpoint = /frachtraum
10
+ tmtargets = depot1/TimeMachine/user1,depot1/TimeMachine/user2
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'frachtraum'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'frachtraum'
8
+ spec.version = Frachtraum::VERSION
9
+ spec.date = '2014-09-11'
10
+ spec.summary = "zfs container management tool"
11
+ spec.description = "lorem ipsum"
12
+ spec.author = "Maximilian Irro"
13
+ spec.email = 'max@disposia.org'
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = ['frachtraum']
16
+ spec.homepage = 'https://github.com/mpgirro/frachtraum'
17
+ spec.license = 'MIT'
18
+
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+
23
+ spec.add_dependency 'thor', '~> 0.19.1'
24
+ spec.add_dependency 'highline', '~> 1.6.21'
25
+ spec.add_dependency 'parseconfig', '~> 1.0.4'
26
+ spec.add_dependency 'rainbow', '~> 2.0.0'
27
+
28
+ end
@@ -0,0 +1,75 @@
1
+ module Frachtraum
2
+
3
+ REQUIRED_TOOLS_BSD = ['dd','grep','gpart','glabel','geli','zfs','zpool']
4
+
5
+
6
+ def attach_bsd(password, depot=nil)
7
+
8
+ # if we provided a specific depot, run procedure only on that one
9
+ depots = depot.nil? ? DEPOTS : [ depot ]
10
+
11
+ # first of all, decrypt and mount all depots
12
+ depots.each do |depot|
13
+ print "decrypting /dev/label/#{depot}..."
14
+
15
+ output = %x( echo #{password} | geli attach -d -j - /dev/label/#{depot} 2>&1 )
16
+ if $?.success?
17
+ output = %x( zfs mount #{depot} 2>&1 )
18
+ if $?.success? then puts "DONE"
19
+ else puts "FAILED! --> #{output}" end
20
+ else
21
+ puts "FAILED! --> #{output}"
22
+ end
23
+ end # each
24
+
25
+ # mount timemachine targets as well
26
+ TIMEMACHINE_TARGETS.each do |tmtarget|
27
+ print "mounting timemachine target #{tmtarget}..."
28
+
29
+ output = %x( zfs mount #{tmtarget} 2>&1 )
30
+ if $?.success? then puts "DONE"
31
+ else puts "FAILED! --> #{output}" end
32
+ end
33
+
34
+ # restart samba so it reports the correct pool size
35
+ print "restarting samba server..."
36
+ output = %x( /usr/local/etc/rc.d/samba restart 2>&1 )
37
+ if $?.success? then puts "DONE"
38
+ else puts "FAILED! --> #{output}" end
39
+ end
40
+
41
+ def setupdisk_bsd(dev, label, password, compression, encryption, keylength, mountpoint)
42
+
43
+ # TODO password promt, confirmation question, etc..
44
+ abort "implementation not ready yet"
45
+
46
+
47
+ exec_cmd "destroying previous partitioning on /dev/#{dev}...",
48
+ "dd if=/dev/zero of=/dev/#{dev} bs=512 count=1"
49
+
50
+ exec_cmd "creating gpart container on /dev/#{dev}...",
51
+ "gpart create -s GPT #{dev}"
52
+
53
+ exec_cmd "labeling /dev/#{dev} with '#{label}'...",
54
+ "glabel label -v #{label} /dev/#{dev}"
55
+
56
+ exec_cmd "initialising /dev/#{dev} as password protected GEOM provider with #{encryption} encryption...",
57
+ "echo #{password} | geli init -s #{keylength} -e #{encryption} -J - /dev/label/#{label}"
58
+
59
+ exec_cmd "attaching /dev/label/#{label} as GEOM provider, creating device /dev/label/#{label}.eli...",
60
+ "echo #{password} | geli attach -d -j - /dev/label/#{label}"
61
+
62
+ exec_cmd "creating zpool #{mountpoint}/#{label} on encrypted device /dev/label/#{label}.eli...",
63
+ "zpool create -m #{mountpoint}/#{label} #{label} /dev/label/#{label}.eli"
64
+
65
+ exec_cmd "setting compression '#{compression}' for new zfs on #{mountpoint}/#{label}...",
66
+ "zfs set compression=#{compression} #{label}"
67
+
68
+ exec_cmd "setting permissions...",
69
+ "chmod -R 775 #{mountpoint}/#{label}"
70
+
71
+ puts "setup finished"
72
+
73
+ end # setupdisk_bsd
74
+
75
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module Frachtraum
3
+
4
+ CONFIG_FILE = 'frachtraum.conf.example'
5
+
6
+ if File.exists?(CONFIG_FILE)
7
+ config = ParseConfig.new(CONFIG_FILE)
8
+ COMPRESSION = config['compression']
9
+ ENCRYPTION = config['encryption']
10
+ KEYLENGTH = config['keylength']
11
+ MOUNTPOINT = config['mountpoint']
12
+
13
+ DEPOTS = config['depots'].split(',')
14
+ TIMEMACHINE_TARGETS = config['tmtargets'].split(',')
15
+ else
16
+ COMPRESSION = 'lz4'
17
+ ENCRYPTION = 'AES-XTS'
18
+ KEYLENGTH = 4096
19
+ MOUNTPOINT = '/frachtraum'
20
+
21
+ DEPOTS = []
22
+ TIMEMACHINE_TARGETS = []
23
+ end
24
+ end
25
+
@@ -0,0 +1,15 @@
1
+ module Frachtraum
2
+
3
+ REQUIRED_TOOLS_LINUX = [] # not yet supported
4
+
5
+ def attach_linux(password, depot)
6
+ # TODO
7
+ abort "not yet implemented"
8
+ end
9
+
10
+ def setupdisk_linux(dev, label, password, compression, encryption, keylength, mountpoint)
11
+ # TODO
12
+ abort "not yet implemented"
13
+ end # setupdisk_linux
14
+
15
+ end
@@ -0,0 +1,21 @@
1
+ module Frachtraum
2
+
3
+ #
4
+ # Maybe this will come in time, but it is not a priority.
5
+ # There is some literature on disk encryption from the command line:
6
+ # http://krypted.com/mac-security/encrypting-os-x-mountain-lion/
7
+ #
8
+
9
+ REQUIRED_TOOLS_OSX = [] # not yet supported
10
+
11
+ def attach_osx(password, depot)
12
+ # TODO
13
+ abort "not yet implemented"
14
+ end
15
+
16
+ def setupdisk_osx(dev, label, password, compression, encryption, keylength, mountpoint)
17
+ # TODO
18
+ abort "not yet implemented"
19
+ end # setupdisk_osx
20
+
21
+ end
data/lib/frachtraum.rb ADDED
@@ -0,0 +1,155 @@
1
+
2
+
3
+ # author: Maximilian Irro <max@disposia.org>, 2014
4
+
5
+ require 'mkmf' # part of stdlib
6
+ require 'open3'
7
+ require 'parseconfig'
8
+
9
+ require 'frachtraum/config'
10
+ require 'frachtraum/bsd'
11
+ require 'frachtraum/linux'
12
+
13
+
14
+ module Frachtraum
15
+
16
+ VERSION = '0.0.1'.freeze
17
+
18
+
19
+ # Kibibyte, Mebibyte, Gibibyte, etc... all the IEC sizes
20
+ BYTES_IN_KiB = 2**10
21
+ BYTES_IN_MiB = 2**20
22
+ BYTES_IN_GiB = 2**30
23
+ BYTES_IN_TiB = 2**40
24
+
25
+ # these define a KB as 1000 bits, according to the SI prefix
26
+ BYTES_IN_KB = 10**3
27
+ BYTES_IN_MB = 10**6
28
+ BYTES_IN_GB = 10**9
29
+ BYTES_IN_TB = 10**12
30
+
31
+
32
+ def exec_cmd(msg, cmd)
33
+
34
+ print msg
35
+
36
+ Open3.popen2e(cmd) do |stdin, stdout_err, wait_thr|
37
+ puts line while line = stdout_err.gets
38
+
39
+ exit_status = wait_thr.value
40
+ if exit_status.success?
41
+ puts "done"
42
+ else
43
+ abort "FAILED! --> #{stdout_err}"
44
+ end
45
+ end
46
+ end # exec_cmd
47
+
48
+ # ---------------
49
+
50
+ def pretty_SI_bytes(bytes)
51
+ return "%.1f TB" % (bytes.to_f / BYTES_IN_TB) if bytes > BYTES_IN_TB
52
+ return "%.1f GB" % (bytes.to_f / BYTES_IN_GB) if bytes > BYTES_IN_GB
53
+ return "%.1f MB" % (bytes.to_f / BYTES_IN_MB) if bytes > BYTES_IN_MB
54
+ return "%.1f KB" % (bytes.to_f / BYTES_IN_KB) if bytes > BYTES_IN_KB
55
+ return "#{bytes} B"
56
+ end
57
+ module_function :pretty_SI_bytes
58
+
59
+ def pretty_IEC_bytes(bytes)
60
+ return "%.1f TiB" % (bytes.to_f / BYTES_IN_TiB) if bytes > BYTES_IN_TiB
61
+ return "%.1f GiB" % (bytes.to_f / BYTES_IN_GiB) if bytes > BYTES_IN_GiB
62
+ return "%.1f MiB" % (bytes.to_f / BYTES_IN_MiB) if bytes > BYTES_IN_MiB
63
+ return "%.1f KiB" % (bytes.to_f / BYTES_IN_KiB) if bytes > BYTES_IN_KiB
64
+ return "#{bytes} B"
65
+ end
66
+ module_function :pretty_IEC_bytes
67
+
68
+ def attach(password, depot=nil)
69
+ case RUBY_PLATFORM
70
+ when /bsd/ then attach_bsd password, depot
71
+ when /linux/ then attach_linux password, depot
72
+ end
73
+ end
74
+ module_function :attach
75
+
76
+ def capacity()
77
+ total_used = 0
78
+ total_avail = 0
79
+ DEPOTS.each do |depot|
80
+ used = %x( zfs get -o value -Hp used #{MOUNTPOINT}/#{depot} )
81
+ avail = %x( zfs get -o value -Hp available #{MOUNTPOINT}/#{depot} )
82
+
83
+ total_used += (used =="" ? 0 : used).to_i # / 1000 # 1024
84
+ total_avail += (avail=="" ? 0 : avail).to_i # / 1000 # 1024
85
+ end
86
+
87
+ total = total_used + total_avail
88
+
89
+ return {:total => total, :avail => total_avail, :used => total_used}
90
+ end
91
+ module_function :capacity
92
+
93
+
94
+ def setupdisk(dev, label, password, compression, encryption, keylength, mountpoint)
95
+
96
+ abort "untested procedure -- won't continue"
97
+
98
+ case RUBY_PLATFORM
99
+ when /bsd/ then setupdisk_bsd dev, label, password, compression, encryption, keylength, mountpoint
100
+ when /linux/ then setupdisk_linux dev, label, password, compression, encryption, keylength, mountpoint
101
+ else abort "OS not supported"
102
+ end
103
+ end
104
+ module_function :setupdisk
105
+
106
+
107
+ def run_system_test()
108
+ tool_list = []
109
+ case RUBY_PLATFORM
110
+ when /bsd/ then tool_list = REQUIRED_TOOLS_BSD
111
+ when /linux/ then tool_list = REQUIRED_TOOLS_LINUX
112
+ else abort "OS not supported"
113
+ end
114
+
115
+ tool_list.each do |tool|
116
+ find_executable tool
117
+ end
118
+
119
+ # find_executable seems to create such file in case executable is not found
120
+ File.delete 'mkmf.log' if File.exists?('mkmf.log')
121
+ end # run_system_test
122
+ module_function :run_system_test
123
+
124
+
125
+ def zfs_dataset_exists?(dataset)
126
+ output = %x( zfs get -H mounted #{dataset} 2>&1 )
127
+ case output
128
+ when /yes/
129
+ return true
130
+ when /dataset does not exist/, /permission denied/
131
+ return false
132
+ else
133
+ abort "can't handle output of zfs_dataset_exists?: #{output}"
134
+ end
135
+ end
136
+ module_function :zfs_dataset_exists?
137
+
138
+ def zfs_dataset_compression_ratio(dataset)
139
+ cmd = "zfs get compressratio #{dataset} | grep compressratio"
140
+ Open3.popen2e(cmd) do |stdin, stdout_err, wait_thr|
141
+ output = stdout_err.gets
142
+ if output == ""
143
+ return "N/A"
144
+ else
145
+ parts = output.split(' ')
146
+ return parts[2] # => ratio
147
+ end
148
+ end
149
+ end
150
+ module_function :zfs_dataset_compression_ratio
151
+
152
+ end # Frachtraum
153
+
154
+
155
+
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frachtraum
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Maximilian Irro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.19.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.19.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: highline
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.21
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.21
41
+ - !ruby/object:Gem::Dependency
42
+ name: parseconfig
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: rainbow
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 2.0.0
69
+ description: lorem ipsum
70
+ email: max@disposia.org
71
+ executables:
72
+ - frachtraum
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - Gemfile
77
+ - LICENSE
78
+ - README.md
79
+ - bin/frachtraum
80
+ - frachtraum.conf.example
81
+ - frachtraum.gemspec
82
+ - lib/frachtraum.rb
83
+ - lib/frachtraum/bsd.rb
84
+ - lib/frachtraum/config.rb
85
+ - lib/frachtraum/linux.rb
86
+ - lib/frachtraum/osx.rb
87
+ homepage: https://github.com/mpgirro/frachtraum
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: 1.9.3
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.1
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: zfs container management tool
111
+ test_files: []