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 +15 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +5 -0
- data/bin/frachtraum +199 -0
- data/frachtraum.conf.example +10 -0
- data/frachtraum.gemspec +28 -0
- data/lib/frachtraum/bsd.rb +75 -0
- data/lib/frachtraum/config.rb +25 -0
- data/lib/frachtraum/linux.rb +15 -0
- data/lib/frachtraum/osx.rb +21 -0
- data/lib/frachtraum.rb +155 -0
- metadata +111 -0
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
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
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
|
data/frachtraum.gemspec
ADDED
@@ -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: []
|