macOS support (#54)
This commit is contained in:
commit
92689b6ee8
53
driver/vm.go
53
driver/vm.go
|
@ -41,15 +41,16 @@ type CreateConfig struct {
|
|||
DiskThinProvisioned bool
|
||||
DiskControllerType string // example: "scsi", "pvscsi"
|
||||
|
||||
Annotation string
|
||||
Name string
|
||||
Folder string
|
||||
Host string
|
||||
ResourcePool string
|
||||
Datastore string
|
||||
GuestOS string // example: otherGuest
|
||||
Network string // "" for default network
|
||||
NetworkCard string // example: vmxnet3
|
||||
Annotation string
|
||||
Name string
|
||||
Folder string
|
||||
Host string
|
||||
ResourcePool string
|
||||
Datastore string
|
||||
GuestOS string // example: otherGuest
|
||||
Network string // "" for default network
|
||||
NetworkCard string // example: vmxnet3
|
||||
USBController bool
|
||||
}
|
||||
|
||||
func (d *Driver) NewVM(ref *types.ManagedObjectReference) *VirtualMachine {
|
||||
|
@ -108,6 +109,14 @@ func (d *Driver) CreateVM(config *CreateConfig) (*VirtualMachine, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if config.USBController {
|
||||
t := true
|
||||
usb := &types.VirtualUSBController{
|
||||
EhciEnabled: &t,
|
||||
}
|
||||
devices = append(devices, usb)
|
||||
}
|
||||
|
||||
createSpec.DeviceChange, err = devices.ConfigSpec(types.VirtualDeviceConfigSpecOperationAdd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -446,12 +455,12 @@ func (vm *VirtualMachine) AddCdrom(isoPath string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ide, err := devices.FindIDEController("")
|
||||
sata, err := vm.FindSATAController()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cdrom, err := devices.CreateCdrom(ide)
|
||||
cdrom, err := vm.CreateCdrom(sata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -519,3 +528,25 @@ func (vm *VirtualMachine) addDevice(device types.BaseVirtualDevice) error {
|
|||
func convertGiBToKiB(gib int64) int64 {
|
||||
return gib * 1024 * 1024
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) AddConfigParams(params map[string]string) error {
|
||||
var confSpec types.VirtualMachineConfigSpec
|
||||
|
||||
var ov []types.BaseOptionValue
|
||||
for k, v := range params {
|
||||
o := types.OptionValue{
|
||||
Key: k,
|
||||
Value: v,
|
||||
}
|
||||
ov = append(ov, &o)
|
||||
}
|
||||
confSpec.ExtraConfig = ov
|
||||
|
||||
task, err := vm.vm.Reconfigure(vm.driver.ctx, confSpec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = task.WaitForResult(vm.driver.ctx, nil)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package driver
|
||||
|
||||
import (
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func (vm *VirtualMachine) AddSATAController() error {
|
||||
sata := &types.VirtualAHCIController{}
|
||||
return vm.addDevice(sata)
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) FindSATAController() (*types.VirtualAHCIController, error) {
|
||||
l, err := vm.Devices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := l.PickController((*types.VirtualAHCIController)(nil))
|
||||
if c == nil {
|
||||
return nil, errors.New("no available SATA controller")
|
||||
}
|
||||
|
||||
return c.(*types.VirtualAHCIController), nil
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) CreateCdrom(c *types.VirtualAHCIController) (*types.VirtualCdrom, error) {
|
||||
l, err := vm.Devices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
device := &types.VirtualCdrom{}
|
||||
|
||||
l.AssignController(device, c)
|
||||
|
||||
device.Backing = &types.VirtualCdromAtapiBackingInfo{
|
||||
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{},
|
||||
}
|
||||
|
||||
device.Connectable = &types.VirtualDeviceConnectInfo{
|
||||
AllowGuestControl: true,
|
||||
Connected: true,
|
||||
StartConnected: true,
|
||||
}
|
||||
|
||||
return device, nil
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"builders": [
|
||||
{
|
||||
"type": "vsphere-iso",
|
||||
|
||||
"vcenter_server": "vcenter.vsphere65.test",
|
||||
"username": "root",
|
||||
"password": "jetbrains",
|
||||
"insecure_connection": "true",
|
||||
|
||||
"vm_name": "macos-packer",
|
||||
"host": "esxi-mac.vsphere65.test",
|
||||
|
||||
"guest_os_type": "darwin16_64Guest",
|
||||
|
||||
"CPUs": 1,
|
||||
"RAM": 4096,
|
||||
|
||||
"disk_size": 32,
|
||||
"disk_thin_provisioned": true,
|
||||
|
||||
"network_card": "e1000e",
|
||||
"usb_controller": true,
|
||||
|
||||
"configuration_parameters": {
|
||||
"ich7m.present": "TRUE",
|
||||
"smc.present": "TRUE"
|
||||
},
|
||||
|
||||
"iso_paths": [
|
||||
"[datastore-mac] ISO/macOS 10.13.3.iso",
|
||||
"[datastore-mac] ISO/setup.iso",
|
||||
"[datastore-mac] ISO/VMware Tools/10.2.0/darwin.iso"
|
||||
],
|
||||
|
||||
"boot_order": "disk,cdrom",
|
||||
|
||||
"boot_wait": "4m",
|
||||
"boot_command": [
|
||||
"<enter><wait5>",
|
||||
"<leftCtrlOn><f2><leftCtrlOff>u<enter>t<enter><wait5>",
|
||||
"/Volumes/setup/setup.sh<enter>"
|
||||
],
|
||||
|
||||
"ssh_username": "jetbrains",
|
||||
"ssh_password": "jetbrains"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
out/
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
set -eux
|
||||
|
||||
# Based on
|
||||
# https://gist.github.com/agentsim/00cc38c693e7d0e1b36a2080870d955b#gistcomment-2304505
|
||||
|
||||
mkdir -p out
|
||||
|
||||
hdiutil create -o out/HighSierra.cdr -size 5530m -layout SPUD -fs HFS+J
|
||||
hdiutil attach out/HighSierra.cdr.dmg -noverify -mountpoint /Volumes/install_build
|
||||
sudo /Applications/Install\ macOS\ High\ Sierra.app/Contents/Resources/createinstallmedia --volume /Volumes/install_build --nointeraction
|
||||
hdiutil detach /Volumes/Install\ macOS\ High\ Sierra
|
||||
hdiutil convert out/HighSierra.cdr.dmg -format UDTO -o out/HighSierra.iso
|
||||
mv out/HighSierra.iso.cdr out/HighSierra.iso
|
||||
rm out/HighSierra.cdr.dmg
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -eux
|
||||
|
||||
mkdir -p out/pkgroot
|
||||
rm -rf /out/pkgroot/*
|
||||
|
||||
mkdir -p out/scripts
|
||||
rm -rf /out/scripts/*
|
||||
cp postinstall out/scripts/
|
||||
|
||||
pkgbuild \
|
||||
--identifier io.packer.install \
|
||||
--root out/pkgroot \
|
||||
--scripts out/scripts \
|
||||
out/postinstall.pkg
|
||||
|
||||
mkdir -p out/iso
|
||||
rm -rf out/iso/*
|
||||
cp setup.sh out/iso/
|
||||
productbuild --package out/postinstall.pkg out/iso/postinstall.pkg
|
||||
|
||||
rm out/setup.iso
|
||||
hdiutil makehybrid -iso -joliet -default-volume-name setup -o out/setup.iso out/iso
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Create user account
|
||||
USERNAME=jetbrains
|
||||
PASSWORD=jetbrains
|
||||
dscl . -create "/Users/${USERNAME}"
|
||||
dscl . -create "/Users/${USERNAME}" UserShell /bin/bash
|
||||
dscl . -create "/Users/${USERNAME}" RealName "${USERNAME}"
|
||||
dscl . -create "/Users/${USERNAME}" UniqueID 510
|
||||
dscl . -create "/Users/${USERNAME}" PrimaryGroupID 20
|
||||
dscl . -create "/Users/${USERNAME}" NFSHomeDirectory "/Users/${USERNAME}"
|
||||
dscl . -passwd "/Users/${USERNAME}" "${PASSWORD}"
|
||||
dscl . -append /Groups/admin GroupMembership "${USERNAME}"
|
||||
createhomedir -c
|
||||
|
||||
# Start VMware Tools daemon explicitly
|
||||
launchctl load /Library/LaunchDaemons/com.vmware.launchd.tools.plist
|
||||
|
||||
# Enable SSH
|
||||
systemsetup -setremotelogin on
|
||||
|
||||
# Disable the welcome screen
|
||||
touch "$3/private/var/db/.AppleSetupDone"
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Format partition
|
||||
diskutil eraseDisk JHFS+ Disk disk0
|
||||
|
||||
# Packages are installed in reversed order - why?
|
||||
"/Volumes/Image Volume/Install macOS High Sierra.app/Contents/Resources/startosinstall" \
|
||||
--volume /Volumes/Disk \
|
||||
--converttoapfs no \
|
||||
--agreetolicense \
|
||||
--installpackage "/Volumes/setup/postinstall.pkg" \
|
||||
--installpackage "/Volumes/VMware Tools/Install VMware Tools.app/Contents/Resources/VMware Tools.pkg"
|
|
@ -50,6 +50,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
Config: &b.config.FloppyConfig,
|
||||
Datastore: b.config.Datastore,
|
||||
},
|
||||
&StepConfigParams{
|
||||
Config: &b.config.ConfigParamsConfig,
|
||||
},
|
||||
)
|
||||
|
||||
if b.config.Comm.Type != "none" {
|
||||
|
|
|
@ -22,6 +22,7 @@ type Config struct {
|
|||
CreateConfig `mapstructure:",squash"`
|
||||
CDRomConfig `mapstructure:",squash"`
|
||||
FloppyConfig `mapstructure:",squash"`
|
||||
ConfigParamsConfig `mapstructure:",squash"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ func (s *StepAddCDRom) Run(state multistep.StateBag) multistep.StepAction {
|
|||
vm := state.Get("vm").(*driver.VirtualMachine)
|
||||
|
||||
ui.Say("Adding CDRoms...")
|
||||
if err := vm.AddSATAController(); err != nil {
|
||||
state.Put("error", fmt.Errorf("error adding SATA controller: %v", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
for _, path := range s.Config.ISOPaths {
|
||||
if err := vm.AddCdrom(path); err != nil {
|
||||
state.Put("error", fmt.Errorf("error adding a cdrom: %v", err))
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package iso
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/jetbrains-infra/packer-builder-vsphere/driver"
|
||||
"github.com/mitchellh/multistep"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ConfigParamsConfig struct {
|
||||
ConfigParams map[string]string `mapstructure:"configuration_parameters"`
|
||||
}
|
||||
|
||||
func (c *ConfigParamsConfig) Prepare() []error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type StepConfigParams struct {
|
||||
Config *ConfigParamsConfig
|
||||
}
|
||||
|
||||
func (s *StepConfigParams) Run(state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
vm := state.Get("vm").(*driver.VirtualMachine)
|
||||
|
||||
ui.Say("Adding configuration parameters...")
|
||||
|
||||
if err := vm.AddConfigParams(s.Config.ConfigParams); err != nil {
|
||||
state.Put("error", fmt.Errorf("error adding configuration parameters: %v", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepConfigParams) Cleanup(state multistep.StateBag) {}
|
|
@ -14,14 +14,15 @@ type CreateConfig struct {
|
|||
DiskThinProvisioned bool `mapstructure:"disk_thin_provisioned"`
|
||||
DiskControllerType string `mapstructure:"disk_controller_type"`
|
||||
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
Folder string `mapstructure:"folder"`
|
||||
Host string `mapstructure:"host"`
|
||||
ResourcePool string `mapstructure:"resource_pool"`
|
||||
Datastore string `mapstructure:"datastore"`
|
||||
GuestOSType string `mapstructure:"guest_os_type"`
|
||||
Network string `mapstructure:"network"`
|
||||
NetworkCard string `mapstructure:"network_card"`
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
Folder string `mapstructure:"folder"`
|
||||
Host string `mapstructure:"host"`
|
||||
ResourcePool string `mapstructure:"resource_pool"`
|
||||
Datastore string `mapstructure:"datastore"`
|
||||
GuestOSType string `mapstructure:"guest_os_type"`
|
||||
Network string `mapstructure:"network"`
|
||||
NetworkCard string `mapstructure:"network_card"`
|
||||
USBController bool `mapstructure:"usb_controller"`
|
||||
}
|
||||
|
||||
func (c *CreateConfig) Prepare() []error {
|
||||
|
@ -79,6 +80,7 @@ func (s *StepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
|
|||
GuestOS: s.Config.GuestOSType,
|
||||
Network: s.Config.Network,
|
||||
NetworkCard: s.Config.NetworkCard,
|
||||
USBController: s.Config.USBController,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue