From 6e651a53fac84e86ab1fd788a6618494c348d48c Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Sat, 28 Nov 2020 21:21:01 +0100 Subject: [PATCH] Creates, saves and restores snapshots. --- src/main.cr | 79 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/src/main.cr b/src/main.cr index 68f73a0..1d176e5 100644 --- a/src/main.cr +++ b/src/main.cr @@ -14,9 +14,7 @@ class Baguette::Configuration end end -module Baguette::Base - getter configuration : Configuration - +module Baguette::Log def info(text) STDOUT << (":: ".colorize :blue) << (text.colorize :white) << "\n" end @@ -26,10 +24,16 @@ module Baguette::Base end def error(text) - STDERR << (":: ".colorize :red) << (text.colorize :white) << "\n" + STDERR << (":: ".colorize :red) << (text.colorize :red) << "\n" end end +module Baguette::Base + getter configuration : Configuration + + include Baguette::Log +end + Colorize.on_tty_only! # CAUTION @@ -48,7 +52,15 @@ class RootFS::Context commands = { "new" => ->(args : Array(String)){ - } + RootFS.new args[1], args[0] + }, + "save" => ->(args : Array(String)){ + RootFS.load(args[0]).save(args[1]) + }, + "restore" => ->(args : Array(String)){ + RootFS.load(args[0]).restore(args[1]) + }, + # FIXME: This needs access to the list of commands. "help" => ->(args : Array(String)){ STDOUT << options_parser << "\n" } @@ -64,6 +76,11 @@ class RootFS::Context Colorize.enabled = true end + parser.on "-h", "--help", "Displays this help message." do + STDOUT << parser << "\n" + exit 0 + end + # FIXME: This leads to unusual behaviors when using the CLI. # Replace by dedicated executables. parser.unknown_args do |args| @@ -71,7 +88,7 @@ class RootFS::Context raise "no command provided" if args.size < 1 - command = args.pop + command = args.shift arguments = args end end @@ -91,6 +108,8 @@ class RootFS::Context end class RootFS::RootFS + include Baguette::Log + getter directory : String def initialize(@directory) @@ -103,13 +122,37 @@ class RootFS::RootFS instance end + protected def execute(command : String) + info "Executing: #{command}" + r = Process.new( + "sh", ["-c", command], + input: Process::Redirect::Inherit, + output: Process::Redirect::Inherit, + error: Process::Redirect::Inherit + ).wait + + raise "Command returned #{r.exit_status}." unless r.success? + end + + # FIXME: Abstract process calls. + # FIXME: REmove the sudos. + protected def create!(template : String) - show! - puts "UNIMPLEMENTED: creating rootfs here" + # FIXME: Alternate backends. + # FIXME: template string parsing. + is_btrfs = true # FIXME: do the actual detection + + unless is_btrfs + raise "can only create rootfs in a btrfs filesystem" + end + + execute "btrfs subvolume create '#{@directory}'" + + execute "debootstrap --arch amd64 '#{template}' '#{@directory}'" end def self.load(directory) - new directory, nil + new directory end def delete @@ -117,28 +160,28 @@ class RootFS::RootFS puts "UNIMPLEMENTED: removing rootfs directory here" end - def save - show! - puts "UNIMPLEMENTED: updating snapshot here" + def save(snapshot_directory) + execute "btrfs subvolume snapshot '#{@directory}' '#{snapshot_directory}'" end - def restore - show! - puts "UNIMPLEMENTED: restoring from snapshot here" + def restore(snapshot_directory) + unmount + execute "btrfs subvolume delete '#{@directory}'" + execute "btrfs subvolume snapshot '#{snapshot_directory}' '#{@directory}'" end - def mount + def mount(directory = nil) show! puts "UNIMPLEMENTED: binding file systems here" end - def unmount + def unmount(directory = nil) show! puts "UNIMPLEMENTED: unbinding file systems here" end def show! - puts "#{@template}, #{@directory}" + puts "#{@directory}" end end