-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathvagrant-reboot-plugin.rb
155 lines (130 loc) · 4.55 KB
/
vagrant-reboot-plugin.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# A quick hack to allow rebooting of a Vagrant VM during provisioning.
#
# This is tested with Vagrant 1.4.3 and 1.6.1. It may work with slightly
# earlier versions, but definitely won't work with 1.3.* or earlier. The code
# is fragile with respect to internal changes in Vagrant, as there is no
# useful public API that allows a reboot to be engineered.
#
# Originally adapted from: https://gist.github.com/ukabu/6780121
#
# This file should be placed into the same folder as your Vagrantfile.
#
# The provisioner takes care of remounting the synced folders.
#
# This will work for the VirtualBox provider. For other providers, a
# 'remount_synced_folders' action must be added to the provider
# implementation.
require 'vagrant'
# Monkey-patch the VirtualBox provider to be able to remap synced folders
# after reboot. This is the tricky part.
#
# This involves pulling out some code fragments from the existing
# SyncedFolders class - which is unpleasant, but there are no usefully exposed
# methods such that we can run only what we need to.
module VagrantPlugins
module ProviderVirtualBox
module Action
class RemountSyncedFolders < SyncedFolders
def initialize(app, env)
super(app, env)
end
def call(env)
@env = env
@app.call(env)
# Copied out of /lib/vagrant/action/builtin/synced_folders.rb in
# Vagrant 1.4.3, and surprisingly still working in 1.6.1.
#
# This is going to be fragile with respect to future changes, but
# that's just the way the cookie crumbles.
#
# We can't just run the whole SyncedFolders.call() method because
# it undertakes a lot more setup and will error out if invoked twice
# during "vagrant up" or "vagrant provision".
folders = synced_folders(env[:machine])
folders.each do |impl_name, fs|
plugins[impl_name.to_sym][0].new.enable(env[:machine], fs, impl_opts(impl_name, env))
end
end
end
def self.action_remount_synced_folders
Vagrant::Action::Builder.new.tap do |b|
b.use RemountSyncedFolders
end
end
end
end
end
# Define the plugin.
class RebootPlugin < Vagrant.plugin('2')
name 'Reboot Plugin'
# This plugin provides a provisioner called unix_reboot.
provisioner 'unix_reboot' do
# Create a provisioner.
class RebootProvisioner < Vagrant.plugin('2', :provisioner)
# Initialization, define internal state. Nothing needed.
def initialize(machine, config)
super(machine, config)
end
# Configuration changes to be done. Nothing needed here either.
def configure(root_config)
super(root_config)
end
# Run the provisioning.
def provision
command = 'shutdown -r now'
@machine.ui.info("Issuing command: #{command}")
@machine.communicate.sudo(command) do |type, data|
if type == :stderr
@machine.ui.error(data);
end
end
begin
sleep 5
end until @machine.communicate.ready?
# Now the machine is up again, perform the necessary tasks.
@machine.ui.info("Launching remount_synced_folders action...")
@machine.action('remount_synced_folders')
end
# Nothing needs to be done on cleanup.
def cleanup
super
end
end
RebootProvisioner
end
# This plugin provides a provisioner called windows_reboot.
provisioner 'windows_reboot' do
# Create a provisioner.
class RebootProvisioner < Vagrant.plugin('2', :provisioner)
# Initialization, define internal state. Nothing needed.
def initialize(machine, config)
super(machine, config)
end
# Configuration changes to be done. Nothing needed here either.
def configure(root_config)
super(root_config)
end
# Run the provisioning.
def provision
command = 'shutdown -t 0 -r -f'
@machine.ui.info("Issuing command: #{command}")
@machine.communicate.execute(command) do |type, data|
if type == :stderr
@machine.ui.error(data);
end
end
begin
sleep 5
end until @machine.communicate.ready?
# Now the machine is up again, perform the necessary tasks.
@machine.ui.info("Launching remount_synced_folders action...")
@machine.action('remount_synced_folders')
end
# Nothing needs to be done on cleanup.
def cleanup
super
end
end
RebootProvisioner
end
end