frachtraum 0.0.1

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.
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: []