161 lines
4.1 KiB
Ruby
161 lines
4.1 KiB
Ruby
require 'to_lvm_xfs'
|
|
|
|
class Raspibian < Base
|
|
def initialize *args
|
|
@vgname = "raspi_#{SecureRandom.urlsafe_base64 5}"
|
|
super *args
|
|
end
|
|
|
|
def build
|
|
ENV['LANG'] = 'C'
|
|
mkmppaths
|
|
|
|
lsblk( dest.image).each do |l|
|
|
d "Device #{l[:name]} mounted at #{l[:mountpoint]}", ! l[:mountpoint]
|
|
end
|
|
|
|
d "Base image does not exist", base.image.exist?
|
|
base_parts = kpartx base.image
|
|
d "two partitions in base expected, got: #{base_parts.inspect}", 2 == base_parts.length
|
|
mount base_parts[1], base.root, -:oro
|
|
mount base_parts[0], base.root+'boot', -:oro
|
|
|
|
dest.image.open 'w' do |f|
|
|
f << 0.chr*4096
|
|
f.pos = 4.8*1024*1024*1024-1
|
|
f.putc 0.chr
|
|
end
|
|
sh.parted dest.image, *%w[--
|
|
mklabel msdos
|
|
mkpart primary fat32 4MB 132MB
|
|
mkpart primary ext2 132MB -1s
|
|
set 2 LVM on
|
|
print]
|
|
|
|
*dest_parts =
|
|
begin
|
|
lsblk( dest.image).select do |l|
|
|
STDERR.puts l
|
|
sh.dmsetup :remove, File.basename(l[:name]) if 'lvm' == l[:type]
|
|
l[:name].start_with?( dest.image.to_s) and 'part' == l[:type]
|
|
end.map {|l| Pathname.new l[:name] }.sort
|
|
rescue Sh::ProcessError
|
|
kpartx dest.image
|
|
end
|
|
d "two partitions in destination expected", 2 == dest_parts.length
|
|
dest_parts[0].open( 'w') {|f| f << 0.chr*4*1024*1024 }
|
|
dest_parts[1].open( 'w') {|f| f << 0.chr*4*1024*1024 }
|
|
sh.vgscan '--cache'
|
|
vgpath = Pathname.new( '/dev') + vgname
|
|
sh.pvcreate '-ff', dest_parts[1]
|
|
sh.vgcreate vgname, dest_parts[1]
|
|
sh.lvcreate -:nroot, '-L4.2G', vgname
|
|
sh.lvcreate -:nhome, '-L100M', vgname
|
|
sh.vgchange -:ae, vgname
|
|
sh.mkvfat -:nboot, dest_parts[0]
|
|
sh.mkxfs -:Lroot, vgpath+'root'
|
|
sh.mkxfs -:Lhome, vgpath+'home'
|
|
mount vgpath+'root', dest.root
|
|
addmp = {}
|
|
%i[home boot].each do |n|
|
|
d = addmp[n] = dest.root+n.to_s
|
|
d.mkdir
|
|
end
|
|
mount vgpath+'home', addmp[:home]
|
|
mount dest_parts[0], addmp[:boot]
|
|
|
|
sh.rsync_all "#{base.root}/", dest.root
|
|
#sh.rsync *%w[kernel7.img initrd7.img], addmp[:boot]
|
|
|
|
rename_user
|
|
|
|
msg :patch, 'etc/fstab'
|
|
(dest.root+'etc'+'fstab').replace_i do |f|
|
|
replace = {
|
|
'/' => "UUID=#{sh.fs_uuid vgpath+'root'} / xfs defaults,noatime 0 0",
|
|
'/boot' => "UUID=#{sh.fs_uuid dest_parts[0]} /boot vfat defaults 1 1",
|
|
'/home' => "UUID=#{sh.fs_uuid vgpath+'home'} /home xfs defaults,noatime 1 1",
|
|
}
|
|
f.each_line.flat_map do |l|
|
|
mp = l.split( /\s+/)[1]
|
|
replace.delete( mp) || l
|
|
end + replace.values
|
|
end
|
|
|
|
msg :patch, 'boot/config.txt'
|
|
(addmp[:boot]+'config.txt').replace_i do |f|
|
|
replace = {
|
|
initramfs: 'initramfs initrd7.img followkernel',
|
|
}
|
|
f.each_line.flat_map do |l|
|
|
l.chomp!
|
|
case l
|
|
when /^initramfs /
|
|
replace.delete :initramfs
|
|
else l
|
|
end
|
|
end + replace.values
|
|
end
|
|
|
|
msg :touch, 'boot/ssh'
|
|
(addmp[:boot]+'ssh').open('w') {|f|}
|
|
|
|
msg :patch, 'boot/cmdline.txt'
|
|
(addmp[:boot]+'cmdline.txt').replace_i do |f|
|
|
lines = f.readlines
|
|
d "Only one line in cmdline.txt expected", 1 == lines.length
|
|
opts = {}
|
|
lines[0].split( ' ').each do |line|
|
|
/^([^=]*)(?:=(.*))?/ =~ line
|
|
opts[$1.to_sym] = $2
|
|
end
|
|
opts[:root] = vgpath+'root'
|
|
opts[:rootfstype] = :xfs
|
|
opts.delete :init
|
|
opts.map {|k,v| v ? "#{k}=#{v}" : "#{k}" }.join(' ')
|
|
end
|
|
|
|
msg :patch, 'etc/initramfs-tools/initramfs.conf'
|
|
dest.root.join( 'etc/initramfs-tools/initramfs.conf').replace_i do |f|
|
|
f.each_line.flat_map do |l|
|
|
l.chomp!
|
|
case l
|
|
when /^COMPRESS=/
|
|
'COMPRESS=xz'
|
|
when /^# *COMPRESS=/
|
|
[l, 'COMPRESS=xz']
|
|
else
|
|
l
|
|
end
|
|
end
|
|
end
|
|
|
|
set_hostname
|
|
|
|
msg :unlinking, 'etc/rc*.d/*resize2fs_once'
|
|
(dest.root+'etc').chdir do
|
|
Pathname.glob( 'rc*.d/*resize2fs_once').each do |fn|
|
|
fn.unlink
|
|
end
|
|
end
|
|
|
|
qemu_bin = dest.root.join 'usr/bin/qemu-arm-static'
|
|
msg :copy, "/usr/bin/qemu-arm-static"
|
|
qemu_bin.copy '/usr/bin/qemu-arm-static', preserve: true
|
|
|
|
ish = sh.chroot dest.root
|
|
ish.apt :update
|
|
ish.apt :upgrade, -:y
|
|
ish.apt :update
|
|
ish.apt :install, -:y, :lvm2, :xfsprogs
|
|
|
|
install_packages_from_dir(
|
|
Pathname.new($0).expand_path.dirname+'raspbian-files',
|
|
Pathname.new('files')
|
|
)
|
|
|
|
# generates implicite initramfs
|
|
ish.system *%w[dpkg-reconfigure raspberrypi-kernel]
|
|
end
|
|
end
|