Refactor building iso

This commit is contained in:
sophia 2020-07-07 14:43:35 -05:00
parent 4a77060805
commit b1d1c20ff7
6 changed files with 89 additions and 61 deletions

View File

@ -1,3 +1,6 @@
require "tempfile"
require "fileutils"
require "pathname"
require "vagrant/util/directory"
require "vagrant/util/subprocess"
@ -6,17 +9,35 @@ module Vagrant
module Caps
module BuildISO
BUILD_ISO_CMD = "".freeze
# Check that the host has the ability to generate ISOs
#
# @param [Vagrant::Environment] env
# @return [Boolean]
def isofs_available(env)
if !self.const_defined?(:BUILD_ISO_CMD)
raise NotImplementedError
end
!!Vagrant::Util::Which.which(self::BUILD_ISO_CMD)
end
def ensure_file_destination(file_destination)
# Builds an iso given a compatible iso_command
#
# @param [List<String>] command to build iso
# @param [Pathname] input directory for iso build
# @param [Pathname] output file for iso build
def build_iso(iso_command, source_directory, file_destination)
FileUtils.mkdir_p(file_destination.dirname)
if !file_destination.exist? || Vagrant::Util::Directory.directory_changed?(source_directory, file_destination.mtime)
result = Vagrant::Util::Subprocess.execute(*iso_command)
if result.exit_code != 0
raise Vagrant::Errors::ISOBuildFailed, cmd: iso_command.join(" "), stdout: result.stdout, stderr: result.stderr
end
end
end
protected
def ensure_output_iso(file_destination)
if file_destination.nil?
tmpfile = Tempfile.new(["vagrant", ".iso"])
file_destination = Pathname.new(tmpfile.path)
@ -29,11 +50,8 @@ module Vagrant
file_destination = file_destination.join("#{SecureRandom.hex(3)}_vagrant.iso")
end
end
# Ensure destination directory is available
FileUtils.mkdir_p(file_destination.dirname)
file_destination
end
end
end
end

View File

@ -1,8 +1,4 @@
require "tempfile"
require 'fileutils'
require 'pathname'
require "vagrant/util/subprocess"
require "vagrant/util/directory"
require "pathname"
require "vagrant/util/caps"
module VagrantPlugins
@ -27,25 +23,15 @@ module VagrantPlugins
# for recent modifications and a new ISO will be generated if requried.
def self.create_iso(env, source_directory, **extra_opts)
source_directory = Pathname.new(source_directory)
file_destination = self.ensure_file_destination(extra_opts[:file_destination])
# If the destrination does not exist or there have been changes in the source directory since the last build, then build
if !file_destination.exist? || Vagrant::Util::Directory.directory_changed?(source_directory, file_destination.mtime)
@@logger.info("Building ISO from source #{source_directory}")
iso_command = [BUILD_ISO_CMD, "makehybrid"]
iso_command << "-hfs"
iso_command << "-iso"
iso_command << "-joliet"
iso_command << "-ov"
iso_command.concat(["-default-volume-name", extra_opts[:volume_id]]) if extra_opts[:volume_id]
iso_command << "-o"
iso_command << file_destination.to_s
iso_command << source_directory.to_s
result = Vagrant::Util::Subprocess.execute(*iso_command)
if result.exit_code != 0
raise Vagrant::Errors::ISOBuildFailed, cmd: iso_command.join(" "), stdout: result.stdout, stderr: result.stderr
end
end
file_destination = self.ensure_output_iso(extra_opts[:file_destination])
iso_command = [BUILD_ISO_CMD, "makehybrid", "-hfs", "-iso", "-joliet", "-ov"]
iso_command.concat(["-default-volume-name", extra_opts[:volume_id]]) if extra_opts[:volume_id]
iso_command << "-o"
iso_command << file_destination.to_s
iso_command << source_directory.to_s
self.build_iso(iso_command, source_directory, file_destination)
@@logger.info("ISO available at #{file_destination}")
file_destination
end

View File

@ -1,8 +1,4 @@
require "tempfile"
require 'fileutils'
require 'pathname'
require "vagrant/util/subprocess"
require "vagrant/util/directory"
require "pathname"
require "vagrant/util/caps"
module VagrantPlugins
@ -27,23 +23,14 @@ module VagrantPlugins
# for recent modifications and a new ISO will be generated if requried.
def self.create_iso(env, source_directory, **extra_opts)
source_directory = Pathname.new(source_directory)
file_destination = self.ensure_file_destination(extra_opts[:file_destination])
file_destination = self.ensure_output_iso(extra_opts[:file_destination])
# If the destrination does not exist or there have been changes in the source directory since the last build, then build
if !file_destination.exist? || Vagrant::Util::Directory.directory_changed?(source_directory, file_destination.mtime)
@@logger.info("Building ISO from source #{source_directory}")
iso_command = [BUILD_ISO_CMD]
iso_command << "-joliet"
iso_command.concat(["-volid", extra_opts[:volume_id]]) if extra_opts[:volume_id]
iso_command << "-o"
iso_command << file_destination.to_s
iso_command << source_directory.to_s
result = Vagrant::Util::Subprocess.execute(*iso_command)
if result.exit_code != 0
raise Vagrant::Errors::ISOBuildFailed, cmd: iso_command.join(" "), stdout: result.stdout, stderr: result.stderr
end
end
iso_command = [BUILD_ISO_CMD, "-joliet"]
iso_command.concat(["-volid", extra_opts[:volume_id]]) if extra_opts[:volume_id]
iso_command << "-o"
iso_command << file_destination.to_s
iso_command << source_directory.to_s
self.build_iso(iso_command, source_directory, file_destination)
@@logger.info("ISO available at #{file_destination}")
file_destination

View File

@ -13,11 +13,6 @@ describe VagrantPlugins::HostDarwin::Cap::FsISO do
expect(Vagrant::Util::Which).to receive(:which).and_return(true)
expect(subject.isofs_available(env)).to eq(true)
end
it "does not find iso building utility when not available" do
expect(Vagrant::Util::Which).to receive(:which).and_return(false)
expect(subject.isofs_available(env)).to eq(false)
end
end
describe ".create_iso" do

View File

@ -13,11 +13,6 @@ describe VagrantPlugins::HostLinux::Cap::FsISO do
expect(Vagrant::Util::Which).to receive(:which).and_return(true)
expect(subject.isofs_available(env)).to eq(true)
end
it "does not find iso building utility when not available" do
expect(Vagrant::Util::Which).to receive(:which).and_return(false)
expect(subject.isofs_available(env)).to eq(false)
end
end
describe ".create_iso" do

View File

@ -0,0 +1,47 @@
require File.expand_path("../../../base", __FILE__)
require "vagrant/util/caps"
describe Vagrant::Util::Caps do
describe "BuildISO" do
class TestSubject
extend Vagrant::Util::Caps::BuildISO
BUILD_ISO_CMD = "test".freeze
end
let(:subject) { TestSubject }
let(:env) { double("env") }
describe ".isofs_available" do
it "finds iso building utility when available" do
expect(Vagrant::Util::Which).to receive(:which).and_return(true)
expect(subject.isofs_available(env)).to eq(true)
end
it "does not find iso building utility when not available" do
expect(Vagrant::Util::Which).to receive(:which).and_return(false)
expect(subject.isofs_available(env)).to eq(false)
end
end
describe ".build_iso" do
let(:file_destination) { Pathname.new("/woo/out.iso") }
before do
allow(file_destination).to receive(:exists?).and_return(false)
allow(FileUtils).to receive(:mkdir_p)
end
it "should run command" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with("test", "cmd").and_return(double(exit_code: 0))
subject.build_iso(["test", "cmd"], "/src/dir", file_destination)
end
it "raise an error if command fails" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with("test", "cmd").and_return(double(exit_code: 1, stdout: "oh no", stderr: "oh no"))
expect{ subject.build_iso(["test", "cmd"], "/src/dir", file_destination) }.to raise_error(Vagrant::Errors::ISOBuildFailed)
end
end
end
end