Module: Frachtraum
- Extended by:
- Frachtraum
- Included in:
- Frachtraum
- Defined in:
- lib/frachtraum.rb,
lib/frachtraum/bsd.rb,
lib/frachtraum/cli.rb,
lib/frachtraum/osx.rb,
lib/frachtraum/linux.rb,
lib/frachtraum/config.rb
Defined Under Namespace
Classes: CLI
Constant Summary collapse
- VERSION =
'0.0.12'.freeze
- BYTES_IN_KiB =
Kibibyte, Mebibyte, Gibibyte, etc… all the IEC sizes
2**10
- BYTES_IN_MiB =
2**20
- BYTES_IN_GiB =
2**30
- BYTES_IN_TiB =
2**40
- BYTES_IN_KB =
these define a KB as 1000 bits, according to the SI prefix
10**3
- BYTES_IN_MB =
10**6
- BYTES_IN_GB =
10**9
- BYTES_IN_TB =
10**12
- OUTPUT_DOTS_LEN =
TODO: the length should be dynamically calculated, based on the strlen of longest tmtarget or volume
40
- CHECKMARK =
> ✓
"\u2713"
- BALLOTX =
> ✗
"\u2717"
- REQUIRED_TOOLS_BSD =
['dd','grep','gpart','glabel','geli','zfs','zpool']
- REQUIRED_TOOLS_OSX =
Maybe this will come in time, but it is not a priority. There is some literature on disk encryption from the command line: krypted.com/mac-security/encrypting-os-x-mountain-lion/
[]
- REQUIRED_TOOLS_LINUX =
not yet supported
[]
- COMPRESSION =
'lz4'
- ENCRYPTION =
'AES-XTS'
- KEYLENGTH =
4096
- MOUNTPOINT =
'/frachtraum'
- VOLUMES =
[]
- TIMEMACHINE_TARGETS =
[]
Class Method Summary collapse
- .attach(password, volume = nil) ⇒ Object
- .capacity ⇒ Object
- .pretty_IEC_bytes(bytes) ⇒ Object
-
.pretty_SI_bytes(bytes) ⇒ Object
—————.
- .report ⇒ Object
- .run_system_test ⇒ Object
- .setupdisk(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
- .sweep(volume) ⇒ Object
- .zfs_volume_exists?(dataset) ⇒ Boolean
Instance Method Summary collapse
- #attach_bsd(password, volume = nil) ⇒ Object
- #attach_linux(password, volume) ⇒ Object
-
#attach_osx(password, volume) ⇒ Object
not yet supported.
- #exec_cmd(msg, cmd) ⇒ Object
- #setupdisk_bsd(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
- #setupdisk_linux(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
- #setupdisk_osx(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
Class Method Details
.attach(password, volume = nil) ⇒ Object
73 74 75 76 77 78 79 80 |
# File 'lib/frachtraum.rb', line 73 def attach(password, volume=nil) case RUBY_PLATFORM when /bsd/ then attach_bsd password, volume when /linux/ then attach_linux password, volume #when /darwin/ then attach_osx password, volume else abort "OS not supported" end end |
.capacity ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/frachtraum.rb', line 83 def capacity() total_used = 0 total_avail = 0 Frachtraum::VOLUMES.each do |volume| used = %x( zfs get -o value -Hp used #{volume} 2>&1 ) avail = %x( zfs get -o value -Hp available #{volume} 2>&1 ) total_used += (used =="" ? 0 : used).to_i # / 1000 # 1024 total_avail += (avail=="" ? 0 : avail).to_i # / 1000 # 1024 end total = total_used + total_avail return {:total => total, :avail => total_avail, :used => total_used} end |
.pretty_IEC_bytes(bytes) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/frachtraum.rb', line 64 def pretty_IEC_bytes(bytes) return "%.1f TiB" % (bytes.to_f / BYTES_IN_TiB) if bytes > BYTES_IN_TiB return "%.1f GiB" % (bytes.to_f / BYTES_IN_GiB) if bytes > BYTES_IN_GiB return "%.1f MiB" % (bytes.to_f / BYTES_IN_MiB) if bytes > BYTES_IN_MiB return "%.1f KiB" % (bytes.to_f / BYTES_IN_KiB) if bytes > BYTES_IN_KiB return "#{bytes} B" end |
.pretty_SI_bytes(bytes) ⇒ Object
55 56 57 58 59 60 61 |
# File 'lib/frachtraum.rb', line 55 def pretty_SI_bytes(bytes) return "%.1f TB" % (bytes.to_f / BYTES_IN_TB) if bytes > BYTES_IN_TB return "%.1f GB" % (bytes.to_f / BYTES_IN_GB) if bytes > BYTES_IN_GB return "%.1f MB" % (bytes.to_f / BYTES_IN_MB) if bytes > BYTES_IN_MB return "%.1f KB" % (bytes.to_f / BYTES_IN_KB) if bytes > BYTES_IN_KB return "#{bytes} B" end |
.report ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/frachtraum.rb', line 100 def report() report_table = {} reported_values = [:used,:available,:compression,:compressratio] (Frachtraum::VOLUMES + Frachtraum::TIMEMACHINE_TARGETS).each do |dataset| volume_info = {} # fetch the values if zfs_volume_exists?(dataset) reported_values.each do |repval| volume_info[repval] = %x( zfs get -o value -Hp #{repval.to_s} #{dataset} ) end else reported_values.each {|repval| volume_info[repval] = "N/A" } end # calculate a total size for each volume volume_info[:total] = if volume_info[:used]=="N/A" || volume_info[:available]=="N/A" "N/A" else (volume_info[:used].to_i + volume_info[:available].to_i) end volume_info[:usage] = if volume_info[:total] == 0 "0 %" elsif volume_info[:used]=="N/A" || volume_info[:total]=="N/A" "N/A" elsif volume_info[:available].to_i == 0 "100 %" else (100 * volume_info[:used].to_f / volume_info[:total].to_f ).to_i.to_s + " %" end report_table[dataset] = volume_info end return report_table end |
.run_system_test ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/frachtraum.rb', line 173 def run_system_test() tool_list = [] case RUBY_PLATFORM when /bsd/ then tool_list = REQUIRED_TOOLS_BSD when /linux/ then tool_list = REQUIRED_TOOLS_LINUX #when /darwin/ then tool_list = REQUIRED_TOOLS_OSX else abort "OS not supported" end tool_list.each { |tool| find_executable tool } # find_executable seems to create such file in case executable is not found File.delete 'mkmf.log' if File.exists?('mkmf.log') end |
.setupdisk(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/frachtraum.rb', line 144 def setupdisk(dev, label, password, compression, encryption, keylength, mountpoint) abort "untested procedure -- won't continue" case RUBY_PLATFORM when /bsd/ then setupdisk_bsd dev, label, password, compression, encryption, keylength, mountpoint when /linux/ then setupdisk_linux dev, label, password, compression, encryption, keylength, mountpoint #when /darwin/ then setupdisk_osx dev, label, password, compression, encryption, keylength, mountpoint else abort "OS not supported" end end |
.sweep(volume) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/frachtraum.rb', line 157 def sweep(volume) target_volumes = volume.nil? ? Frachtraum::VOLUMES : volume # TODO abort "sweeping not supported yet" target_volumes.each do |volume| if zfs_volume_exists?(volume) # TODO end end end |
.zfs_volume_exists?(dataset) ⇒ Boolean
190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/frachtraum.rb', line 190 def zfs_volume_exists?(dataset) output = %x( zfs get -H mounted #{dataset} 2>&1 ) case output when /yes/ return true when /dataset does not exist/, /permission denied/ return false else abort "can't handle output of zfs_volume_exists?: #{output}" end end |
Instance Method Details
#attach_bsd(password, volume = nil) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/frachtraum/bsd.rb', line 5 def attach_bsd(password, volume=nil) # if we provided a specific depot, run procedure only on that one volumes = volume.nil? ? Frachtraum::VOLUMES : [ volume ] # first of all, decrypt and mount all depots volumes.each do |v| print "decrypting #{v}...".ljust(OUTPUT_DOTS_LEN,".") output = %x( echo #{password} | geli attach -d -j - /dev/label/#{v} 2>&1 ) if $?.success? output = %x( zfs mount #{v} 2>&1 ) if $?.success? then puts Rainbow(CHECKMARK).green else puts Rainbow("#{BALLOTX}\n#{output}").red end else puts Rainbow("#{BALLOTX}\n#{output}").red end end # volumes.each # mount timemachine targets as well Frachtraum::TIMEMACHINE_TARGETS.each do |tmtarget| print "mounting #{tmtarget}...".ljust(OUTPUT_DOTS_LEN,".") output = %x( zfs mount #{tmtarget} 2>&1 ) if $?.success? then puts Rainbow(CHECKMARK).green else puts Rainbow("#{BALLOTX}\n#{output}").red end end # restart samba so it reports the correct pool size print "restarting samba server...".ljust(OUTPUT_DOTS_LEN,".") output = %x( /usr/local/etc/rc.d/samba restart 2>&1 ) if $?.success? then puts Rainbow(CHECKMARK).green else puts Rainbow("#{BALLOTX}\n#{output}").red end end |
#attach_linux(password, volume) ⇒ Object
5 6 7 8 |
# File 'lib/frachtraum/linux.rb', line 5 def attach_linux(password, volume) # TODO abort "not yet implemented" end |
#attach_osx(password, volume) ⇒ Object
not yet supported
11 12 13 14 |
# File 'lib/frachtraum/osx.rb', line 11 def attach_osx(password, volume) # TODO abort "not yet implemented" end |
#exec_cmd(msg, cmd) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/frachtraum.rb', line 37 def exec_cmd(msg, cmd) print msg Open3.popen2e(cmd) do |stdin, stdout_err, wait_thr| puts line while line = stdout_err.gets exit_status = wait_thr.value if exit_status.success? puts Rainbow("done").green else abort Rainbow("FAILED!").red + " --> #{stdout_err}" end end end |
#setupdisk_bsd(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/frachtraum/bsd.rb', line 41 def setupdisk_bsd(dev, label, password, compression, encryption, keylength, mountpoint) # TODO password promt, confirmation question, etc.. abort "implementation not ready yet" exec_cmd "destroying previous partitioning on /dev/#{dev}...", "dd if=/dev/zero of=/dev/#{dev} bs=512 count=1" exec_cmd "creating gpart container on /dev/#{dev}...", "gpart create -s GPT #{dev}" exec_cmd "labeling /dev/#{dev} with '#{label}'...", "glabel label -v #{label} /dev/#{dev}" exec_cmd "initialising /dev/#{dev} as password protected GEOM provider with #{encryption} encryption...", "echo #{password} | geli init -s #{keylength} -e #{encryption} -J - /dev/label/#{label}" exec_cmd "attaching /dev/label/#{label} as GEOM provider, creating device /dev/label/#{label}.eli...", "echo #{password} | geli attach -d -j - /dev/label/#{label}" exec_cmd "creating zpool #{mountpoint}/#{label} on encrypted device /dev/label/#{label}.eli...", "zpool create -m #{mountpoint}/#{label} #{label} /dev/label/#{label}.eli" exec_cmd "setting compression '#{compression}' for new zfs on #{mountpoint}/#{label}...", "zfs set compression=#{compression} #{label}" exec_cmd "setting permissions...", "chmod -R 775 #{mountpoint}/#{label}" puts "setup finished" end |
#setupdisk_linux(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
10 11 12 13 |
# File 'lib/frachtraum/linux.rb', line 10 def setupdisk_linux(dev, label, password, compression, encryption, keylength, mountpoint) # TODO abort "not yet implemented" end |
#setupdisk_osx(dev, label, password, compression, encryption, keylength, mountpoint) ⇒ Object
16 17 18 19 |
# File 'lib/frachtraum/osx.rb', line 16 def setupdisk_osx(dev, label, password, compression, encryption, keylength, mountpoint) # TODO abort "not yet implemented" end |