Build iso for Darwin host
This commit is contained in:
parent
f5a957f949
commit
e1d104a8e3
@ -428,6 +428,10 @@ module Vagrant
|
||||
error_key(:host_explicit_not_detected)
|
||||
end
|
||||
|
||||
class ISOBuildFailed < VagrantError
|
||||
error_key(:iso_build_failed)
|
||||
end
|
||||
|
||||
class LinuxMountFailed < VagrantError
|
||||
error_key(:linux_mount_failed)
|
||||
end
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
require "tempfile"
|
||||
require 'fileutils'
|
||||
require 'pathname'
|
||||
require "vagrant/util/subprocess"
|
||||
require "vagrant/util/map_command_options"
|
||||
|
||||
module VagrantPlugins
|
||||
module HostDarwin
|
||||
@ -6,12 +10,14 @@ module VagrantPlugins
|
||||
class FsISO
|
||||
@@logger = Log4r::Logger.new("vagrant::host::darwin::fs_iso")
|
||||
|
||||
BUILD_ISO_CMD = "hdiutil".freeze
|
||||
|
||||
# Check that the host has the ability to generate ISOs
|
||||
#
|
||||
# @param [Vagrant::Environment] env
|
||||
# @return [Boolean]
|
||||
def self.isofs_available(env)
|
||||
!!Vagrant::Util::Which.which("hdiutil")
|
||||
!!Vagrant::Util::Which.which(BUILD_ISO_CMD)
|
||||
end
|
||||
|
||||
# Generate an ISO file of the given source directory
|
||||
@ -19,26 +25,34 @@ module VagrantPlugins
|
||||
# @param [Vagrant::Environment] env
|
||||
# @param [String, Pathname] source_directory Contents of ISO
|
||||
# @param [String, Pathname, nil] file_destination Location to store ISO
|
||||
# @param [Map] extra arguments to pass to the iso building command
|
||||
# @return [Pathname] ISO location
|
||||
# @note If file_destination exists, source_directory will be checked
|
||||
# for recent modifications and a new ISO will be generated if requried.
|
||||
def self.create_iso(env, source_directory, file_destination=nil)
|
||||
def self.create_iso(env, source_directory, file_destination=nil, extra_opts={})
|
||||
if file_destination.nil?
|
||||
tmpfile = Tempfile.new("vagrant-iso")
|
||||
file_destination = Pathname.new(tmpfile.path)
|
||||
tmpfile.delete
|
||||
else
|
||||
file_destination = Pathname.new(file_destination.to_s)
|
||||
end
|
||||
source_directory = Pathname.new(source_directory)
|
||||
if iso_update_required?(file_destination, source_directory)
|
||||
# Ensure destination directory is available
|
||||
FileUtils.mkdir_p(file_destination.to_s)
|
||||
result = Vagrant::Util::Subprocess.execute("hdiutil", "makehybrid", "-o",
|
||||
file_destination.to_s, "-hfs", "-joliet", "-iso", "-default-volume-name",
|
||||
"cidata", source_directory.to_s)
|
||||
end
|
||||
source_directory = Pathname.new(source_directory)
|
||||
if iso_update_required?(file_destination, source_directory)
|
||||
iso_command = [BUILD_ISO_CMD, "makehybrid"]
|
||||
iso_command << "-hfs"
|
||||
iso_command << "-iso"
|
||||
iso_command << "-joliet"
|
||||
iso_command.concat(Vagrant::Util::MapCommandOptions.map_to_command_options(extra_opts, cmd_flag="-"))
|
||||
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 "Failed to create ISO!"
|
||||
raise Vagrant::Errors::ISOBuildFailed, cmd: iso_command.join(" "), stdout: result.stdout, stderr: result.stderr
|
||||
end
|
||||
end
|
||||
file_destination
|
||||
@ -51,10 +65,11 @@ module VagrantPlugins
|
||||
# @return [Boolean]
|
||||
def self.iso_update_required?(iso_path, dir_path)
|
||||
Dir.glob(dir_path.join("**/**/*")).each do |path|
|
||||
if File.mtime > iso_path.mtime
|
||||
if Pathname.new(path).mtime > iso_path.mtime
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@logger.info("ISO update not required! No changes found in source path #{dir_path}")
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
require "vagrant"
|
||||
|
||||
module VagrantPlugins
|
||||
module Kernel_V2
|
||||
class CloudInit < Vagrant.plugin("2", :config)
|
||||
|
||||
DEFAULT_SOURCE_PATTERN = "**/**/*".freeze
|
||||
|
||||
attr_accessor :iso_path
|
||||
attr_accessor :source_files_pattern
|
||||
attr_accessor :source_directory
|
||||
|
||||
def initialize
|
||||
@iso_path = UNSET_VALUE
|
||||
@source_files_pattern = UNSET_VALUE
|
||||
@source_directory = UNSET_VALUE
|
||||
end
|
||||
|
||||
def finalize!
|
||||
if @iso_path != UNSET_VALUE
|
||||
@iso_path = Pathname.new(@iso_path.to_s)
|
||||
else
|
||||
@iso_path = nil
|
||||
end
|
||||
if @source_files_pattern == UNSET_VALUE
|
||||
@source_files_pattern = DEFAULT_SOURCE_PATTERN
|
||||
end
|
||||
if @source_directory != UNSET_VALUE
|
||||
@source_directory = Pathname.new(@source_directory.to_s)
|
||||
else
|
||||
@source_directory = nil
|
||||
end
|
||||
end
|
||||
|
||||
def validate(machine)
|
||||
errors = _detected_errors
|
||||
if @source_directory.nil? || !@source_directory.exist?
|
||||
errors << I18n.t("vagrant.config.cloud_init.invalid_source_directory",
|
||||
directory: source_directory.to_s)
|
||||
end
|
||||
|
||||
{"cloud_init" => errors}
|
||||
end
|
||||
|
||||
def to_s
|
||||
"CloudInit"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -15,9 +15,9 @@ module VagrantPlugins
|
||||
# "kernel_v1", none of these configuration classes are upgradable.
|
||||
# This is by design, since we can't be sure if they're upgradable
|
||||
# until another version is available.
|
||||
config("cloud_init") do
|
||||
require File.expand_path("../config/cloud_init", __FILE__)
|
||||
CloudInit
|
||||
config("ssh") do
|
||||
require File.expand_path("../config/ssh", __FILE__)
|
||||
SSHConfig
|
||||
end
|
||||
|
||||
config("package") do
|
||||
@ -30,11 +30,6 @@ module VagrantPlugins
|
||||
PushConfig
|
||||
end
|
||||
|
||||
config("ssh") do
|
||||
require File.expand_path("../config/ssh", __FILE__)
|
||||
SSHConfig
|
||||
end
|
||||
|
||||
config("vagrant") do
|
||||
require File.expand_path("../config/vagrant", __FILE__)
|
||||
VagrantConfig
|
||||
|
||||
@ -939,6 +939,18 @@ en:
|
||||
("%{value}") could not be found. Please verify that the plugin is
|
||||
installed which implements this host and that the value you used
|
||||
for `config.vagrant.host` is correct.
|
||||
iso_build_failed: |-
|
||||
Failed to build iso image. The following command returned an error:
|
||||
|
||||
%{cmd}
|
||||
|
||||
Stdout from the command:
|
||||
|
||||
%{stdout}
|
||||
|
||||
Stderr from the command:
|
||||
|
||||
%{stderr}
|
||||
hyperv_virtualbox_error: |-
|
||||
Hyper-V and VirtualBox cannot be used together and will result in a
|
||||
system crash. Vagrant will now exit. Please disable Hyper-V if you wish
|
||||
|
||||
61
test/unit/plugins/hosts/darwin/cap/fs_iso_test.rb
Normal file
61
test/unit/plugins/hosts/darwin/cap/fs_iso_test.rb
Normal file
@ -0,0 +1,61 @@
|
||||
require 'pathname'
|
||||
|
||||
require_relative "../../../../base"
|
||||
require_relative "../../../../../../plugins/hosts/darwin/cap/fs_iso"
|
||||
|
||||
describe VagrantPlugins::HostDarwin::Cap::FsISO do
|
||||
include_context "unit"
|
||||
|
||||
let(:subject){ VagrantPlugins::HostDarwin::Cap::FsISO }
|
||||
|
||||
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 ".create_iso" do
|
||||
before do
|
||||
allow(subject).to receive(:iso_update_required?).and_return(true)
|
||||
allow(FileUtils).to receive(:mkdir_p)
|
||||
end
|
||||
|
||||
it "builds an iso" do
|
||||
expect(Vagrant::Util::Subprocess).to receive(:execute).with(
|
||||
"hdiutil", "makehybrid", "-hfs", "-iso", "-joliet", "-o", /.iso/, /\/foo\/src/
|
||||
).and_return(double(exit_code: 0))
|
||||
|
||||
output = subject.create_iso(env, "/foo/src", "/woo/out.iso")
|
||||
expect(output.to_s).to eq("/woo/out.iso")
|
||||
end
|
||||
|
||||
it "builds an iso with args" do
|
||||
expect(Vagrant::Util::Subprocess).to receive(:execute).with(
|
||||
"hdiutil", "makehybrid", "-hfs", "-iso", "-joliet", "-default-volume-name", "cidata", "-o", /.iso/, /\/foo\/src/
|
||||
).and_return(double(exit_code: 0))
|
||||
|
||||
output = subject.create_iso(env, "/foo/src", "/woo/out.iso", extra_opts={"default-volume-name" => "cidata"})
|
||||
expect(output.to_s).to eq("/woo/out.iso")
|
||||
end
|
||||
|
||||
it "raises an error if iso build failed" do
|
||||
allow(Vagrant::Util::Subprocess).to receive(:execute).with(any_args).and_return(double(stdout: "nope", stderr: "nope", exit_code: 1))
|
||||
expect{ subject.create_iso(env, "/foo/src", "/woo/out.iso") }.to raise_error(Vagrant::Errors::ISOBuildFailed)
|
||||
end
|
||||
|
||||
it "does not build iso if no changes required" do
|
||||
allow(subject).to receive(:iso_update_required?).and_return(false)
|
||||
expect(Vagrant::Util::Subprocess).to_not receive(:execute)
|
||||
output = subject.create_iso(env, "/foo/src", "/woo/out.iso", extra_opts={"default-volume-name" => "cidata"})
|
||||
expect(output.to_s).to eq("/woo/out.iso")
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user