getch 0.1.9 → 0.3.3

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.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +132 -0
  4. data/LICENSE +10 -0
  5. data/README.md +35 -29
  6. data/bin/getch +8 -6
  7. data/getch.gemspec +31 -0
  8. data/lib/clean.rb +149 -0
  9. data/lib/cryptsetup.rb +132 -0
  10. data/lib/devs.rb +199 -0
  11. data/lib/dracut/encrypt.rb +36 -0
  12. data/lib/dracut/hybrid.rb +15 -0
  13. data/lib/dracut/lvm.rb +14 -0
  14. data/lib/dracut/minimal.rb +11 -0
  15. data/lib/dracut/root.rb +45 -0
  16. data/lib/dracut/zfs.rb +35 -0
  17. data/lib/dracut.rb +11 -0
  18. data/lib/fstab/encrypt.rb +44 -0
  19. data/lib/fstab/hybrid.rb +34 -0
  20. data/lib/fstab/lvm.rb +25 -0
  21. data/lib/fstab/minimal.rb +6 -0
  22. data/lib/fstab/root.rb +93 -0
  23. data/lib/fstab/zfs.rb +23 -0
  24. data/lib/fstab.rb +11 -0
  25. data/lib/getch/assembly.rb +150 -0
  26. data/lib/getch/command.rb +88 -128
  27. data/lib/getch/config/account.rb +39 -0
  28. data/lib/getch/config/dhcp.rb +104 -0
  29. data/lib/getch/config/grub.rb +42 -0
  30. data/lib/getch/config/iwd.rb +60 -0
  31. data/lib/getch/config/keymap.rb +78 -0
  32. data/lib/getch/config/locale.rb +96 -0
  33. data/lib/getch/config/portage.rb +90 -0
  34. data/lib/getch/config/pre_network.rb +37 -0
  35. data/lib/getch/config/timezone.rb +52 -0
  36. data/lib/getch/config/void.rb +0 -36
  37. data/lib/getch/config.rb +16 -37
  38. data/lib/getch/device.rb +67 -0
  39. data/lib/getch/filesystem/ext4/encrypt/config.rb +9 -71
  40. data/lib/getch/filesystem/ext4/encrypt/deps.rb +15 -25
  41. data/lib/getch/filesystem/ext4/encrypt/device.rb +11 -5
  42. data/lib/getch/filesystem/ext4/encrypt/format.rb +6 -15
  43. data/lib/getch/filesystem/ext4/encrypt/mount.rb +7 -11
  44. data/lib/getch/filesystem/ext4/encrypt/partition.rb +10 -76
  45. data/lib/getch/filesystem/ext4/encrypt/void.rb +0 -38
  46. data/lib/getch/filesystem/ext4/encrypt.rb +2 -1
  47. data/lib/getch/filesystem/ext4/hybrid/config.rb +27 -0
  48. data/lib/getch/filesystem/ext4/hybrid/deps.rb +55 -0
  49. data/lib/getch/filesystem/ext4/hybrid/device.rb +24 -0
  50. data/lib/getch/filesystem/ext4/hybrid/format.rb +23 -0
  51. data/lib/getch/filesystem/ext4/hybrid/mount.rb +21 -0
  52. data/lib/getch/filesystem/ext4/hybrid/partition.rb +27 -0
  53. data/lib/getch/filesystem/{lvm/encrypt → ext4/hybrid}/void.rb +0 -39
  54. data/lib/getch/filesystem/ext4/hybrid.rb +19 -0
  55. data/lib/getch/filesystem/ext4/lvm/config.rb +25 -0
  56. data/lib/getch/filesystem/ext4/lvm/deps.rb +56 -0
  57. data/lib/getch/filesystem/ext4/lvm/device.rb +28 -0
  58. data/lib/getch/filesystem/ext4/lvm/format.rb +21 -0
  59. data/lib/getch/filesystem/ext4/lvm/mount.rb +21 -0
  60. data/lib/getch/filesystem/ext4/lvm/partition.rb +28 -0
  61. data/lib/getch/filesystem/{lvm.rb → ext4/lvm.rb} +6 -4
  62. data/lib/getch/filesystem/ext4/minimal/config.rb +25 -0
  63. data/lib/getch/filesystem/ext4/{device.rb → minimal/deps.rb} +3 -1
  64. data/lib/getch/filesystem/ext4/minimal/device.rb +22 -0
  65. data/lib/getch/filesystem/ext4/minimal/format.rb +23 -0
  66. data/lib/getch/filesystem/ext4/minimal/mount.rb +21 -0
  67. data/lib/getch/filesystem/ext4/minimal/partition.rb +28 -0
  68. data/lib/getch/filesystem/ext4/minimal.rb +19 -0
  69. data/lib/getch/filesystem/ext4.rb +7 -7
  70. data/lib/getch/filesystem/zfs/encrypt/config.rb +10 -39
  71. data/lib/getch/filesystem/zfs/encrypt/deps.rb +4 -55
  72. data/lib/getch/filesystem/zfs/encrypt/device.rb +7 -51
  73. data/lib/getch/filesystem/zfs/encrypt/format.rb +6 -90
  74. data/lib/getch/filesystem/zfs/encrypt/mount.rb +16 -35
  75. data/lib/getch/filesystem/zfs/encrypt/partition.rb +6 -54
  76. data/lib/getch/filesystem/zfs/encrypt.rb +2 -1
  77. data/lib/getch/filesystem/zfs/minimal/config.rb +37 -0
  78. data/lib/getch/filesystem/zfs/minimal/deps.rb +126 -0
  79. data/lib/getch/filesystem/zfs/minimal/device.rb +24 -0
  80. data/lib/getch/filesystem/zfs/minimal/format.rb +23 -0
  81. data/lib/getch/filesystem/zfs/minimal/mount.rb +23 -0
  82. data/lib/getch/filesystem/zfs/minimal/partition.rb +23 -0
  83. data/lib/getch/filesystem/zfs/minimal.rb +19 -0
  84. data/lib/getch/filesystem/zfs.rb +1 -7
  85. data/lib/getch/filesystem.rb +0 -6
  86. data/lib/getch/gentoo/bootloader.rb +23 -44
  87. data/lib/getch/gentoo/finalize.rb +25 -0
  88. data/lib/getch/gentoo/post_config.rb +75 -0
  89. data/lib/getch/gentoo/pre_config.rb +37 -0
  90. data/lib/getch/gentoo/services.rb +18 -0
  91. data/lib/getch/gentoo/sources.rb +39 -33
  92. data/lib/getch/gentoo/tarball.rb +91 -0
  93. data/lib/getch/gentoo/terraform.rb +34 -0
  94. data/lib/getch/gentoo/update.rb +54 -0
  95. data/lib/getch/gentoo/use.rb +9 -6
  96. data/lib/getch/gentoo/use_flag.rb +17 -20
  97. data/lib/getch/gentoo.rb +9 -75
  98. data/lib/getch/guard.rb +3 -3
  99. data/lib/getch/helpers.rb +63 -115
  100. data/lib/getch/log.rb +87 -25
  101. data/lib/getch/options.rb +41 -11
  102. data/lib/getch/states.rb +28 -8
  103. data/lib/getch/tree.rb +56 -0
  104. data/lib/getch/version.rb +1 -1
  105. data/lib/getch/void/bootloader.rb +18 -0
  106. data/lib/getch/void/finalize.rb +31 -0
  107. data/lib/getch/void/post_config.rb +19 -0
  108. data/lib/getch/void/pre_config.rb +18 -0
  109. data/lib/getch/void/services.rb +18 -0
  110. data/lib/getch/void/{stage.rb → tarball.rb} +34 -14
  111. data/lib/getch/void/terraform.rb +28 -0
  112. data/lib/getch/void/update.rb +33 -0
  113. data/lib/getch/void.rb +9 -59
  114. data/lib/getch.rb +58 -90
  115. data/lib/luks.rb +239 -0
  116. data/lib/lvm2.rb +112 -0
  117. data/lib/mkfs/zfs.rb +167 -0
  118. data/lib/mkfs.rb +144 -0
  119. data/lib/mountfs.rb +154 -0
  120. data/lib/nito.rb +131 -0
  121. data/lib/sgdisk.rb +160 -0
  122. data.tar.gz.sig +0 -0
  123. metadata +113 -74
  124. metadata.gz.sig +0 -0
  125. data/lib/getch/config/gentoo.rb +0 -58
  126. data/lib/getch/filesystem/clean.rb +0 -58
  127. data/lib/getch/filesystem/device.rb +0 -63
  128. data/lib/getch/filesystem/ext4/config.rb +0 -62
  129. data/lib/getch/filesystem/ext4/deps.rb +0 -24
  130. data/lib/getch/filesystem/ext4/format.rb +0 -31
  131. data/lib/getch/filesystem/ext4/mount.rb +0 -26
  132. data/lib/getch/filesystem/ext4/partition.rb +0 -55
  133. data/lib/getch/filesystem/ext4/void.rb +0 -44
  134. data/lib/getch/filesystem/lvm/config.rb +0 -44
  135. data/lib/getch/filesystem/lvm/deps.rb +0 -44
  136. data/lib/getch/filesystem/lvm/device.rb +0 -45
  137. data/lib/getch/filesystem/lvm/encrypt/config.rb +0 -74
  138. data/lib/getch/filesystem/lvm/encrypt/deps.rb +0 -49
  139. data/lib/getch/filesystem/lvm/encrypt/device.rb +0 -48
  140. data/lib/getch/filesystem/lvm/encrypt/format.rb +0 -35
  141. data/lib/getch/filesystem/lvm/encrypt/mount.rb +0 -27
  142. data/lib/getch/filesystem/lvm/encrypt/partition.rb +0 -84
  143. data/lib/getch/filesystem/lvm/encrypt.rb +0 -18
  144. data/lib/getch/filesystem/lvm/format.rb +0 -32
  145. data/lib/getch/filesystem/lvm/mount.rb +0 -26
  146. data/lib/getch/filesystem/lvm/partition.rb +0 -72
  147. data/lib/getch/filesystem/lvm/void.rb +0 -46
  148. data/lib/getch/filesystem/mount.rb +0 -63
  149. data/lib/getch/filesystem/partition.rb +0 -85
  150. data/lib/getch/filesystem/zfs/config.rb +0 -43
  151. data/lib/getch/filesystem/zfs/deps.rb +0 -67
  152. data/lib/getch/filesystem/zfs/device.rb +0 -66
  153. data/lib/getch/filesystem/zfs/encrypt/void.rb +0 -97
  154. data/lib/getch/filesystem/zfs/format.rb +0 -117
  155. data/lib/getch/filesystem/zfs/mount.rb +0 -47
  156. data/lib/getch/filesystem/zfs/partition.rb +0 -69
  157. data/lib/getch/filesystem/zfs/void.rb +0 -81
  158. data/lib/getch/gentoo/boot.rb +0 -64
  159. data/lib/getch/gentoo/chroot.rb +0 -75
  160. data/lib/getch/gentoo/config.rb +0 -167
  161. data/lib/getch/gentoo/stage.rb +0 -73
  162. data/lib/getch/void/boot.rb +0 -84
  163. data/lib/getch/void/chroot.rb +0 -56
  164. data/lib/getch/void/config.rb +0 -90
data/lib/luks.rb ADDED
@@ -0,0 +1,239 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nito'
4
+ require 'getch/log'
5
+ require 'getch/command'
6
+
7
+ module Luks
8
+ class Main
9
+ include Luks
10
+ include NiTo
11
+
12
+ Permission = Class.new(StandardError)
13
+
14
+ def initialize(disk, options)
15
+ @disk = disk
16
+ @format = options[:fs]
17
+ @mountpoint = options[:mountpoint]
18
+ @luks_type = nil
19
+ @key_dir = nil
20
+ @key_name = nil
21
+ @mount = nil
22
+ @bootloader = false
23
+ @log = Getch::Log.new
24
+ @bs = get_bs
25
+ end
26
+
27
+ def encrypt
28
+ args = @luks_type == 'luks2' ? "#{@command_args} --sector-size #{@bs}" : @command_args
29
+ @log.info "Encrypting #{@luks_name} > #{@disk}...\n"
30
+ cmd_crypt 'cryptsetup', 'luksFormat', args, "/dev/#{@disk}"
31
+ end
32
+
33
+ def encrypt_with_key
34
+ make_key
35
+ args = @luks_type == 'luks2' ?
36
+ "#{@command_args} -q --sector-size #{@bs} -d #{@full_key_path}" :
37
+ "#{@command_args} -q -d #{@full_key_path}"
38
+ @log.info "Encrypting #{@luks_name} with #{@full_key_path}...\n"
39
+ cmd_crypt 'cryptsetup', 'luksFormat', args, "/dev/#{@disk}"
40
+ end
41
+
42
+ def open
43
+ return if File.exist? "/dev/mapper/#{@luks_name}"
44
+
45
+ @log.info "Opening #{@luks_name} > #{@disk}...\n"
46
+ cmd_crypt 'cryptsetup', 'open', @command_args, "/dev/#{@disk}", @luks_name
47
+ unless File.exist? "/dev/mapper/#{@luks_name}"
48
+ raise "No dev /dev/mapper/#{@luks_name}, open it first..."
49
+ end
50
+ end
51
+
52
+ def open_with_key(file = nil)
53
+ return if File.exist? "/dev/mapper/#{@luks_name}"
54
+
55
+ @full_key_path = "#{@mountpoint}#{@key_path}"
56
+ key = file ? file : @full_key_path
57
+ @log.info "Opening #{@luks_name} disk #{@disk} with #{key}...\n"
58
+ cmd_crypt 'cryptsetup', 'open', @command_args, '-d', key, "/dev/#{@disk}", @luks_name
59
+ end
60
+
61
+ def format
62
+ case @format
63
+ when 'ext4'
64
+ format_ext4
65
+ when 'xfs'
66
+ format_xfs
67
+ when 'fat'
68
+ format_fat
69
+ else
70
+ @log.fatal "#{@format} not yet supported."
71
+ end
72
+ end
73
+
74
+ def external_key
75
+ make_key
76
+ @log.info "Adding key for #{@luks_name}...\n"
77
+ cmd_crypt 'cryptsetup', 'luksAddKey', "/dev/#{@disk}", @full_key_path
78
+ end
79
+
80
+ def write_config
81
+ config
82
+ perm
83
+ end
84
+
85
+ def mount
86
+ mountpoint = @luks_name =~ /^root/ ? @mountpoint : "#{@mountpoint}#{@mount}"
87
+ NiTo.mount "/dev/mapper/#{@luks_name}", mountpoint
88
+ end
89
+
90
+ def close
91
+ return unless File.exist? "/dev/mapper/#{@luks_name}"
92
+
93
+ @log.info "Closing #{@luks_name}...\n"
94
+ cmd_crypt 'cryptsetup', 'close', @luks_name
95
+ end
96
+
97
+ def gen_datas
98
+ end
99
+
100
+ protected
101
+
102
+ def make_key
103
+ @key_path = "#{@key_dir}/#{@key_name}"
104
+ @full_key_path = "#{@mountpoint}#{@key_path}"
105
+ @log.info "Generating key...\n"
106
+ mkdir "#{@mountpoint}#{@key_dir}"
107
+ sh 'dd', 'bs=512', 'count=8', 'iflag=fullblock', 'if=/dev/urandom', "of=#{@full_key_path}"
108
+ end
109
+
110
+ # https://wiki.archlinux.org/title/Advanced_Format#File_systems
111
+ def format_ext4
112
+ @log.info "Formating disk with #{@format}...\n"
113
+ sh 'mkfs.ext4', '-F', '-b', @bs, "/dev/mapper/#{@luks_name}"
114
+ end
115
+
116
+ # https://wiki.archlinux.org/title/Advanced_Format#File_systems
117
+ def format_xfs
118
+ @log.info "Formating disk with #{@format}...\n"
119
+ sh 'mkfs.xfs', '-f', '-s', "size=#{@bs}", "/dev/mapper/#{@luks_name}"
120
+ end
121
+
122
+ def config
123
+ @key_path = "#{@key_dir}/#{@key_name}"
124
+ uuid = Getch::Helpers.uuid @disk
125
+ @log.info "Writing configs for #{@luks_name}...\n"
126
+
127
+ @log.info " * Writing #{@mountpoint}/etc/crypttab..."
128
+ line = "#{@luks_name} UUID=#{uuid} #{@key_path} luks"
129
+ echo_a "#{@mountpoint}/etc/crypttab", line
130
+ @log.result_ok
131
+
132
+ config_openrc
133
+ config_grub
134
+ end
135
+
136
+ # https://wiki.gentoo.org/wiki/Dm-crypt#Configuring_dm-crypt
137
+ def config_openrc
138
+ Getch::Helpers.openrc? || return
139
+
140
+ conf = "#{@mountpoint}/etc/conf.d/dmcrypt"
141
+ uuid = Getch::Helpers.uuid @disk
142
+ echo_a conf, "target=#{@luks_name}"
143
+ echo_a conf, "source=UUID=\"#{uuid}\""
144
+ echo_a conf, "key=#{@key_path}"
145
+ end
146
+
147
+ def config_grub
148
+ return unless @bootloader
149
+
150
+ if Getch::Helpers.grub?
151
+ @log.info ' * Writing to /etc/default/grub...'
152
+ line = 'GRUB_ENABLE_CRYPTODISK=y'
153
+ echo_a "#{@mountpoint}/etc/default/grub", line
154
+ @log.result_ok
155
+ end
156
+ end
157
+
158
+ def perm
159
+ @key_path = "#{@key_dir}/#{@key_name}"
160
+ @full_key_path = "#{@mountpoint}#{@key_path}"
161
+ @log.info "Enforcing permission on #{@full_key_path}..."
162
+ File.chmod 0400, "#{@mountpoint}#{@key_dir}"
163
+ File.chmod 0000, @full_key_path
164
+ File.chown 0, 0, @full_key_path
165
+ @log.result_ok
166
+ end
167
+
168
+ private
169
+
170
+ def get_bs
171
+ @disk || @log.fatal("No disk for #{@luks_name}.")
172
+
173
+ sh 'blockdev', '--getpbsz', "/dev/#{@disk}"
174
+ end
175
+
176
+ def cmd_crypt_raw(*args)
177
+ system args.join(' ')
178
+ return if $?.exitstatus == 0
179
+
180
+ @log.dbg args.join(' ')
181
+ @log.dbg $?
182
+ @log.fatal 'die'
183
+ end
184
+
185
+ def cmd_crypt(*args)
186
+ cmd_crypt_raw args
187
+ rescue => e
188
+ @log.fatal e
189
+ end
190
+
191
+ def sh(*args)
192
+ Getch::Command.new(args)
193
+ end
194
+ end
195
+
196
+ # Boot can decrypt the root (/)
197
+ class Boot < Main
198
+ def initialize(disk, options)
199
+ super
200
+ @luks_type = 'luks1'
201
+ @key_dir = '/boot'
202
+ @key_name = 'boot.key'
203
+ @bootloader = true
204
+ @mount = '/boot'
205
+ @luks = options[:luks_name]
206
+ @luks_name = "boot-#{@luks}"
207
+ @command_args = "--type #{@luks_type}"
208
+ end
209
+ end
210
+
211
+ # Root can decrypt the /home or other devs
212
+ class Root < Main
213
+ def initialize(disk, options)
214
+ super
215
+ @luks_type = 'luks2'
216
+ @key_dir = '/boot'
217
+ @key_name = 'root.key'
218
+ @luks = options[:luks_name]
219
+ @luks_name = "root-#{@luks}"
220
+ @mount = '/'
221
+ @command_args = "--type #{@luks_type}"
222
+ @bootloader = false
223
+ end
224
+ end
225
+
226
+ class Home < Main
227
+ def initialize(disk, options)
228
+ super
229
+ @luks_type = 'luks2'
230
+ @key_dir = '/root/keys'
231
+ @key_name = 'home.key'
232
+ @mount = '/home'
233
+ @command_args = "--type #{@luks_type}"
234
+ @luks = options[:luks_name]
235
+ @luks_name = "home-#{@luks}"
236
+ @bootloader = false
237
+ end
238
+ end
239
+ end
data/lib/lvm2.rb ADDED
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'getch/command'
4
+
5
+ module Lvm2
6
+ class Root
7
+ def initialize(devs, options)
8
+ @cache = options[:cache_disk] ||= nil
9
+ @root = devs[:root] ||= nil
10
+ @home = options[:home_disk] ||= nil
11
+ @vg = options[:vg_name] ||= 'vg1'
12
+ end
13
+
14
+ def x
15
+ load_datas
16
+ pv_create
17
+ vg_create
18
+ lv_setup
19
+ enable_lvs
20
+ end
21
+
22
+ protected
23
+
24
+ def load_datas
25
+ @path_root = "/dev/#{@root}"
26
+ @path_cache = "/dev/#{@cache}"
27
+ @path_home = "/dev/#{@home}"
28
+ end
29
+
30
+ def pv_create
31
+ devs = [ @path_root ]
32
+ @cache && devs << @path_cache
33
+ @home && devs << @path_home
34
+ devs.each { |d| d && add_pv(d) }
35
+ end
36
+
37
+ def vg_create
38
+ devs = [ @path_root ]
39
+ @cache && devs << @path_cache
40
+ @home && devs << @path_home
41
+ add_vg devs
42
+ end
43
+
44
+ def lv_setup
45
+ @cache ? add_swap(@path_cache) : add_swap
46
+ add_lv_root
47
+ @home ? add_home(@path_home) : add_home
48
+ end
49
+
50
+ def enable_lvs
51
+ lvchange_y 'home'
52
+ lvchange_y 'swap'
53
+ lvchange_y 'root'
54
+ end
55
+
56
+ private
57
+
58
+ def add_pv(dev)
59
+ File.exist? dev || @log.fatal("add_pv - no #{dev} exist.")
60
+
61
+ Getch::Command.new('pvcreate', '-f', dev)
62
+ end
63
+
64
+ def add_vg(*devs)
65
+ Getch::Command.new('vgcreate', '-f', @vg, devs.join(' '))
66
+ end
67
+
68
+ def add_swap(dev = nil)
69
+ mem = Getch::Helpers.get_memory
70
+ lvcreate('-L', mem, '-n', 'swap', @vg, dev)
71
+ end
72
+
73
+ # if home is available, we use the whole space.
74
+ def add_lv_root
75
+ @home ?
76
+ @root.match?(/[0-9]/) ? add_root : add_root(nil, @path_root) :
77
+ @root.match?(/[0-9]/) ? add_root('16G') : add_root('16G', @path_root)
78
+ end
79
+
80
+ def add_root(size = nil, dev = nil)
81
+ arg_size = size ? "-L #{size}" : '-l 100%FREE'
82
+ lvcreate(arg_size, '-n', 'root', @vg, dev)
83
+ end
84
+
85
+ def add_home(dev = nil)
86
+ lvcreate('-l', '100%FREE', '-n', 'home', @vg, dev)
87
+ end
88
+
89
+ def lvcreate(*args)
90
+ Getch::Command.new('lvcreate', '-y', '-Wy', '-Zy', args)
91
+ end
92
+
93
+ def lvchange_y(name)
94
+ return if File.exist? "/dev/#{@vg}/#{name}"
95
+
96
+ Getch::Command.new('lvchange', '-ay', "/dev/#{@vg}/#{name}")
97
+ end
98
+ end
99
+
100
+ class Hybrid < Root
101
+ def initialize(devs, options)
102
+ super
103
+ @luks = options[:luks_name]
104
+ end
105
+
106
+ def load_datas
107
+ @path_root = "/dev/mapper/root-#{@luks}"
108
+ @path_cache = "/dev/mapper/cache-#{@luks}"
109
+ @path_home = "/dev/mapper/home-#{@luks}"
110
+ end
111
+ end
112
+ end
data/lib/mkfs/zfs.rb ADDED
@@ -0,0 +1,167 @@
1
+ require 'getch/log'
2
+
3
+ module Mkfs
4
+ class Zfs < Root
5
+ def initialize(devs, options)
6
+ @mountpoint = options[:mountpoint]
7
+ @zfs = options[:zfs_name] ||= 'pool'
8
+ @os = options[:os]
9
+ @encrypt = options[:encrypt]
10
+ @zlog = devs[:zlog] ||= nil
11
+ @zcache = devs[:zcache] ||= nil
12
+ @rpool = "r#{@zfs}"
13
+ @bpool = "b#{@zfs}"
14
+ @hpool = "h#{@zfs}"
15
+ @log = Getch::Log.new
16
+ super
17
+ end
18
+
19
+ # reorder process, root should be formatted first
20
+ def x
21
+ format_efi
22
+ format_root
23
+ format_boot
24
+ format_swap
25
+ format_home
26
+ add_dataset
27
+ end
28
+
29
+ # https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2020.04%20Root%20on%20ZFS.html#id13
30
+ def format_boot
31
+ @boot || return
32
+
33
+ id = Getch::Helpers.get_id(@boot)
34
+ ashift = get_ashift @boot
35
+ args = "-f -o ashift=#{ashift} -o autotrim=on"
36
+ args << ' -o feature@async_destroy=enabled'
37
+ args << ' -o feature@bookmarks=enabled'
38
+ args << ' -o feature@embedded_data=enabled'
39
+ args << ' -o feature@empty_bpobj=enabled'
40
+ args << ' -o feature@enabled_txg=enabled'
41
+ args << ' -o feature@extensible_dataset=enabled'
42
+ args << ' -o feature@filesystem_limits=enabled'
43
+ args << ' -o feature@hole_birth=enabled'
44
+ args << ' -o feature@large_blocks=enabled'
45
+ args << ' -o feature@lz4_compress=enabled'
46
+ args << ' -o feature@spacemap_histogram=enabled'
47
+ args << ' -O acltype=posixacl -O canmount=off -O compression=lz4'
48
+ args << ' -O devices=off -O normalization=formD -O atime=off -O xattr=sa'
49
+ args << ' -O mountpoint=/boot'
50
+ args << " -R #{@mountpoint} #{@bpool} #{id}"
51
+ sh 'zpool', 'create', args
52
+ end
53
+
54
+ def format_swap
55
+ mk_swap "/dev/#{@swap}"
56
+ add_zlog
57
+ add_zcache
58
+ end
59
+
60
+ def add_zlog
61
+ @zlog || return
62
+
63
+ id = Getch::Helpers.get_id(@zlog)
64
+ sh 'zpool', 'add', @rpool, 'log', id
65
+ end
66
+
67
+ def add_zcache
68
+ @zcache || return
69
+
70
+ id = Getch::Helpers.get_id(@zcache)
71
+ sh 'zpool', 'add', @rpool, 'cache', id
72
+ end
73
+
74
+ def format_root
75
+ id = Getch::Helpers.get_id(@root)
76
+ ashift = get_ashift @root
77
+ args = "-f -o ashift=#{ashift} -o autotrim=on"
78
+ @encrypt && args << ' -O encryption=aes-256-gcm'
79
+ @encrypt && args << ' -O keylocation=prompt -O keyformat=passphrase'
80
+ args << ' -O acltype=posixacl -O canmount=off -O compression=lz4'
81
+ args << ' -O xattr=sa -O mountpoint=/'
82
+ args << " -R #{@mountpoint} #{@rpool} #{id}"
83
+ sh 'zpool', 'create', args
84
+ end
85
+
86
+ def format_home
87
+ @home || return
88
+
89
+ id = Getch::Helpers.get_id(@home)
90
+ ashift = get_ashift @home
91
+ args = "-f -o ashift=#{ashift} -o autotrim=on"
92
+ @encrypt && args << ' -O encryption=aes-256-gcm'
93
+ @encrypt && args << ' -O keylocation=prompt -O keyformat=passphrase'
94
+ args << ' -O acltype=posixacl -O canmount=off -O compression=lz4'
95
+ args << ' -O xattr=sa -O mountpoint=/home'
96
+ args << " -R #{@mountpoint} #{@hpool} #{id}"
97
+ sh 'zpool', 'create', args
98
+ end
99
+
100
+ def add_dataset
101
+ zfs_create "-o canmount=off -o mountpoint=none #{@rpool}/ROOT"
102
+ zfs_create "-o canmount=noauto -o mountpoint=/ #{@rpool}/ROOT/#{@os}"
103
+ Getch::Command.new("zfs mount #{@rpool}/ROOT/#{@os}")
104
+
105
+ zfs_create "-o canmount=off #{@rpool}/ROOT/#{@os}/usr"
106
+ zfs_create "#{@rpool}/ROOT/#{@os}/usr/src"
107
+
108
+ zfs_create "-o canmount=off #{@rpool}/ROOT/#{@os}/var"
109
+ zfs_create "#{@rpool}/ROOT/#{@os}/var/log"
110
+ zfs_create "#{@rpool}/ROOT/#{@os}/var/db"
111
+ zfs_create "#{@rpool}/ROOT/#{@os}/var/tmp"
112
+ zfs_create "#{@rpool}/ROOT/#{@os}/var/lib"
113
+ zfs_create "#{@rpool}/ROOT/#{@os}/var/lib/docker"
114
+
115
+ boot_dataset
116
+ user_dataset
117
+ end
118
+
119
+ def boot_dataset
120
+ @boot || return
121
+
122
+ zfs_create "-o canmount=off -o mountpoint=none #{@bpool}/BOOT"
123
+ zfs_create "-o canmount=noauto -o mountpoint=/boot #{@bpool}/BOOT/#{@os}"
124
+ end
125
+
126
+ def user_dataset
127
+ if @home
128
+ zfs_create "-o canmount=off -o mountpoint=/ #{@hpool}/USERDATA"
129
+ zfs_create "-o canmount=on -o mountpoint=/root #{@hpool}/USERDATA/root"
130
+ zfs_create "-o canmount=on -o mountpoint=/home #{@hpool}/USERDATA/home"
131
+ else
132
+ zfs_create "-o canmount=off -o mountpoint=/ #{@rpool}/USERDATA"
133
+ zfs_create "-o canmount=on -o mountpoint=/root #{@rpool}/USERDATA/root"
134
+ zfs_create "-o canmount=on -o mountpoint=/home #{@rpool}/USERDATA/home"
135
+ end
136
+ end
137
+
138
+ private
139
+
140
+ def get_ashift(dev)
141
+ bs = Getch::Helpers.get_bs("/dev/#{dev}")
142
+ case bs
143
+ when /8096/ then 13
144
+ when /4096/ then 12
145
+ else 9
146
+ end
147
+ end
148
+
149
+ def zfs_create(*args)
150
+ Getch::Command.new('zfs', 'create', args)
151
+ end
152
+
153
+ def sh(*args)
154
+ @encrypt ?
155
+ cmd_crypt(args) :
156
+ Getch::Command.new(args)
157
+ end
158
+
159
+ def cmd_crypt(*args)
160
+ system args.join(' ')
161
+ return if $?.exitstatus == 0
162
+
163
+ @log.dbg $?
164
+ @log.fatal 'die'
165
+ end
166
+ end
167
+ end
data/lib/mkfs.rb ADDED
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'getch/command'
4
+ require 'getch/helpers'
5
+
6
+ module Mkfs
7
+ class Root
8
+ def initialize(devs, options)
9
+ @efi = devs[:efi] ||= nil
10
+ @boot = devs[:boot] ||= nil
11
+ @swap = devs[:swap] ||= nil
12
+ @root = devs[:root] ||= nil
13
+ @home = devs[:home] ||= nil
14
+ @fs = options[:fs]
15
+ x
16
+ end
17
+
18
+ protected
19
+
20
+ def x
21
+ format_efi
22
+ format_boot
23
+ format_swap
24
+ format_root
25
+ format_home
26
+ end
27
+
28
+ def format_efi
29
+ @efi || return
30
+
31
+ mkfs_vfat "/dev/#{@efi}"
32
+ end
33
+
34
+ def format_boot
35
+ @boot || return
36
+
37
+ mkfs "/dev/#{@boot}"
38
+ end
39
+
40
+ def format_swap
41
+ @swap || return
42
+
43
+ mk_swap "/dev/#{@swap}"
44
+ end
45
+
46
+ def format_root
47
+ @root || return
48
+
49
+ mkfs "/dev/#{@root}"
50
+ end
51
+
52
+ def format_home
53
+ @home || return
54
+
55
+ mkfs "/dev/#{@home}"
56
+ end
57
+
58
+ private
59
+
60
+ def mkfs(path)
61
+ case @fs
62
+ when 'ext4' then mkfs_ext4 path
63
+ when 'xfs' then mkfs_xfs path
64
+ end
65
+ end
66
+
67
+ def mkfs_vfat(path)
68
+ Getch::Command.new('mkfs.fat', '-F32', path)
69
+ end
70
+
71
+ def mk_swap(path)
72
+ Getch::Command.new('mkswap', '-f', path)
73
+ end
74
+
75
+ def mkfs_ext4(path)
76
+ bs = Getch::Helpers.get_bs(path)
77
+ if bs == '512'
78
+ Getch::Command.new('mkfs.ext4', '-F', path)
79
+ else
80
+ Getch::Command.new('mkfs.ext4', '-F', '-b', bs, path)
81
+ end
82
+ end
83
+
84
+ def mkfs_xfs(path)
85
+ bs = Getch::Helpers.get_bs(path)
86
+ Getch::Command.new('mkfs.xfs', '-f', '-s', "size=#{bs}", path)
87
+ end
88
+ end
89
+
90
+ class Lvm < Root
91
+ def initialize(devs, options)
92
+ @vg = options[:vg_name]
93
+ super
94
+ end
95
+
96
+ def format_swap
97
+ mk_swap "/dev/#{@vg}/swap"
98
+ end
99
+
100
+ def format_root
101
+ mkfs "/dev/#{@vg}/root"
102
+ end
103
+
104
+ def format_home
105
+ mkfs "/dev/#{@vg}/home"
106
+ end
107
+ end
108
+
109
+ class Encrypt < Root
110
+ def initialize(devs, options)
111
+ @luks = options[:luks_name]
112
+ super
113
+ end
114
+
115
+ # Boot is alrealy formatted
116
+ def format_boot
117
+ end
118
+
119
+ # Swap will be encrypted after the reboot
120
+ def format_swap
121
+ end
122
+
123
+ def format_root
124
+ File.exist? "/dev/mapper/root-#{@luks}" || abort("No root-#{@luks} found")
125
+
126
+ mkfs "/dev/mapper/root-#{@luks}"
127
+ end
128
+
129
+ def format_home
130
+ @home || return
131
+
132
+ mkfs "/dev/mapper/home-#{@luks}"
133
+ end
134
+ end
135
+
136
+ class Hybrid < Lvm
137
+
138
+ # Boot is alrealy formatted
139
+ def format_boot
140
+ end
141
+ end
142
+ end
143
+
144
+ require_relative 'mkfs/zfs'