Skip to content

Commit

Permalink
Added support for Windows Guest VMs
Browse files Browse the repository at this point in the history
  • Loading branch information
dsmaher committed Jun 10, 2015
1 parent fdc78a3 commit dba385f
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 9 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ The disk is initialized and added to it's own volume group as specfied in the co
this defaults to 'vagrant'. An ext4 filesystem is created and the disk mounted appropriately,
with entries added to fstab ... subsequent runs will mount this disk with the options specified

## Windows Guests

Windows Guests must use the WinRM communicator by setting `vm.communicator = 'winrm'`. An additional option is provided to
allow you to set the drive letter using:

```
config.persistent_storage.drive_letter = 'Z'
```

Options that are irrelevent to Windows are ignored, such as `mountname`, `filesystem`, `mountpoint` and `volgroupname`.

## Troubleshooting

If your box are not using LVM you must set `config.persistent_storage.use_lvm = false`.
Expand Down
5 changes: 4 additions & 1 deletion lib/vagrant-persistent-storage/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Config < Vagrant.plugin('2', :config)
attr_accessor :diskdevice
attr_accessor :filesystem
attr_accessor :volgroupname
attr_accessor :drive_letter

alias_method :create?, :create
alias_method :mount?, :mount
Expand All @@ -41,6 +42,7 @@ def initialize
@diskdevice = UNSET_VALUE
@filesystem = UNSET_VALUE
@volgroupname = UNSET_VALUE
@drive_letter = UNSET_VALUE
end

def finalize!
Expand All @@ -58,6 +60,7 @@ def finalize!
@diskdevice = 0 if @diskdevice == UNSET_VALUE
@filesystem = 0 if @filesystem == UNSET_VALUE
@volgroupname = 0 if @volgroupname == UNSET_VALUE
@drive_letter = 0 if @drive_letter == UNSET_VALUE
end

def validate(machine)
Expand Down Expand Up @@ -113,7 +116,7 @@ def validate(machine)
:is_class => volgroupname.class.to_s,
})
end

mount_point_path = Pathname.new("#{machine.config.persistent_storage.location}")
if ! mount_point_path.absolute?
errors << I18n.t('vagrant_persistent_storage.config.not_a_path', {
Expand Down
55 changes: 47 additions & 8 deletions lib/vagrant-persistent-storage/manage_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
module VagrantPlugins
module PersistentStorage
module ManageStorage

def populate_template(m)
mnt_name = m.config.persistent_storage.mountname
mnt_point = m.config.persistent_storage.mountpoint
Expand All @@ -18,6 +17,15 @@ def populate_template(m)
mount = m.config.persistent_storage.mount
format = m.config.persistent_storage.format

## windows filesystem options
drive_letter = m.config.persistent_storage.drive_letter

if m.config.vm.communicator == :winrm
os = "windows"
else
os = "linux"
end

vg_name = 'vps' unless vg_name != 0
disk_dev = '/dev/sdb' unless disk_dev != 0
mnt_name = 'vps' unless mnt_name != 0
Expand All @@ -28,8 +36,25 @@ def populate_template(m)
else
device = "#{disk_dev}1"
end

## shell script to format disk, create/manage LVM, mount disk
if drive_letter == 0
drive_letter = ""
else
drive_letter = "letter=#{drive_letter}"
end

if os == "windows"
## shell script for windows to create NTFS partition and assign drive letter
disk_operations_template = ERB.new <<-EOF
<% if format == true %>
foreach ($disk in get-wmiobject Win32_DiskDrive -Filter "Partitions = 0"){
$disk.DeviceID
$disk.Index
"select disk "+$disk.Index+"`r clean`r create partition primary`r format fs=ntfs unit=65536 quick`r active`r assign #{drive_letter}" | diskpart >> disk_operation_log.txt
}
<% end %>
EOF
else
## shell script to format disk, create/manage LVM, mount disk
disk_operations_template = ERB.new <<-EOF
#!/bin/bash
# fdisk the disk if it's not a block device already:
Expand Down Expand Up @@ -69,24 +94,38 @@ def populate_template(m)
<% end %>
exit $?
EOF
end

buffer = disk_operations_template.result(binding)
tmp_script = Tempfile.new("disk_operations_#{mnt_name}.sh")
target_script = "/tmp/disk_operations_#{mnt_name}.sh"
tmp_script = Tempfile.new("disk_operations_#{mnt_name}.sh")

if os == 'windows'
target_script = "disk_operations_#{mnt_name}.ps1"
else
target_script = "/tmp/disk_operations_#{mnt_name}.sh"
end

File.open("#{tmp_script.path}", 'wb') do |f|
f.write buffer
end
m.communicate.upload(tmp_script.path, target_script)
m.communicate.sudo("chmod 755 #{target_script}")
unless os == 'windows'
m.communicate.sudo("chmod 755 #{target_script}")
end
end

def run_disk_operations(m)
return unless m.communicate.ready?
mnt_name = m.config.persistent_storage.mountname
mnt_name = 'vps' unless mnt_name != 0
target_script = "/tmp/disk_operations_#{mnt_name}.sh"
m.communicate.sudo("#{target_script}")
if m.config.vm.communicator == :winrm
target_script = "disk_operations_#{mnt_name}.ps1"
m.communicate.sudo("powershell -executionpolicy bypass -file #{target_script}")
else
target_script = "/tmp/disk_operations_#{mnt_name}.sh"
m.communicate.sudo("#{target_script}")
end

end

def manage_volumes(m)
Expand Down
22 changes: 22 additions & 0 deletions sample-win-vm/Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "myWindowsBox"

# These are required for Windows machines running under vagrant
config.vm.communicator = "winrm"
config.winrm.username = "Administrator"
config.winrm.password = "Password!"

# configure a persistent storage for mysql data
config.persistent_storage.enabled = true
config.persistent_storage.location = "virtualdrive.vdi"
config.persistent_storage.size = 5000

end

0 comments on commit dba385f

Please sign in to comment.