-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathINSTALL.ps1
331 lines (270 loc) · 9.58 KB
/
INSTALL.ps1
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# Install script for linux-vm project
# by Patrick Wyatt 2/6/2013
#
# To run this script locally:
# @powershell -NoProfile -ExecutionPolicy Unrestricted -File INSTALL.ps1
# - or -
# test.bat
#
# To download and run this script:
# @powershell -NoProfile -ExecutionPolicy Unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://raw.github.com/webcoyote/linux-vm/master/INSTALL.ps1'))"
#
# Fail on errors
$ErrorActionPreference = 'Stop'
#-----------------------------------------------
# Configuration -- change these settings if desired
#-----------------------------------------------
# Where do you like your projects installed?
# For me it is C:\dev but you can change it here:
$DEVELOPMENT_DIRECTORY = $Env:SystemDrive + '\dev'
# By default Chocolatey wants to install to C:\chocolatey
# but lots of folks on Hacker News don't like that. Override
# the default directory here:
$CHOCOLATEY_DIRECTORY = $Env:SystemDrive + '\chocolatey'
# Git has three installation mode:
# 1. Use Git Bash only
# 2. Run Git from the Windows Command Prompt
# 3. Run Git and included Unix tools from the Windows Command Prompt
#
# You probably want #2 or #3 so you can use git from a DOS command shell
# More details: http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/
#
# Suggestion: add "export PATH=/bin:$PATH" to your ~/.bashrc file so
# that git-bash utilities have precedence over Windows utilities with
# the same name, e.g. find.exe
#
# Pick one:
$GIT_INSTALL_MODE=3
#-----------------------------------------------
# Utility functions
#-----------------------------------------------
function Exec
{
[CmdletBinding()]
param (
[Parameter(Position=0, Mandatory=1)]
[ScriptBlock]$Command,
[Parameter(Position=1, Mandatory=0)]
[string]$ErrorMessage = "ERROR: command failed:`n$Command"
)
&$Command
if ($LastExitCode -ne 0) {
write-host $ErrorMessage
exit 1
}
}
<#
# What the fuck!?! PowerShell is supposed to be a scripting language
# for system administrators, not a descent into the bowels of hell!
# I understand *why* this happens, but not *how* a language could be
# designed to work like this!
function Append ([String]$path, [String]$dir) {
[String]::concat($path, ";", $dir)
}
[String]::concat("a;b;c", ";", "d") # => a;b;c;d
Append("a;b;c", "d") # => a;b;c d;
Append "a;b;c", "d" # => a;b;c d;
Append "a;b;c" "d" # => a;b;c;d
#>
#-----------------------------------------------
# Path-handling
#-----------------------------------------------
# AppendPath ";a;b;;c;" ";d;" => a;b;c;d
function AppendPath ([String]$path, [String]$dir) {
$result = $path.split(';') + $dir.split(';') |
where { $_ -ne '' } |
select -uniq
[String]::join(';', $result)
}
function AppendEnvAndGlobalPath ([String]$dir, [String]$target) {
# Add to this shell's environment
$Env:Path = AppendPath $Env:path $dir
# Add to the global environment; $target => { 'Machine', User' }
$path = [Environment]::GetEnvironmentVariable('Path', $target)
$path = AppendPath $path $dir
[Environment]::SetEnvironmentVariable('Path', $path, $target)
}
function FindInRegistryPath ([String]$file) {
[Environment]::GetEnvironmentVariable('Path', 'Machine').split(';') +
[Environment]::GetEnvironmentVariable('Path', 'User').split(';') |
where { $_ -ne '' } |
foreach { join-path $_ $file } |
Where-Object { Test-Path $_ } |
Select-Object -First 1
}
function FindInRegistryPathCheck ([String]$file) {
$fullpath = FindInRegistryPath $file
if ($fullpath -eq $null) {
write-host "ERROR: Cannot find '$fullpath' in the path"
exit 1
}
$fullpath
}
function VerifyInstallation([String]$exe, [String]$versionOption) {
# Find command in path
$cmd = FindInRegistryPath $exe
if ((! $cmd) -or ! (Test-Path $cmd) ) {
write-host "ERROR: I thought I just installed '" + $exe + "' but now I can't find it!"
exit 1
}
# Verify it runs
if ($versionOption) {
&$cmd $versionOption | out-null
if ($LASTEXITCODE -ne 0) {
write-host "ERROR: Unable to run '" + $exe + "'. Did it install correctly?"
exit 1
}
}
$cmd
}
#-----------------------------------------------
# Install Chocolatey package manager
#-----------------------------------------------
function InstallPackageManager () {
# If the chocolatey install directory is not set in this command shell's
# environment then check the global environment
if (! $Env:ChocolateyInstall) {
$Env:ChocolateyInstall = [Environment]::GetEnvironmentVariable('ChocolateyInstall', 'User')
}
# If it still isn't set then use default directory
if (! $Env:ChocolateyInstall) {
$Env:ChocolateyInstall = $CHOCOLATEY_DIRECTORY
}
# Chocolatey already installed?
if (Test-Path "$Env:ChocolateyInstall\bin\cinst.bat") {
write-host "Skipping chocolatey package manager installation"
return
}
# Save install location for future shells. Any shells that have already
# been started will not pick up this environment variable (Windows limitation)
[Environment]::SetEnvironmentVariable(
'ChocolateyInstall',
$Env:ChocolateyInstall,
'User'
)
# Install Chocolatey
$url = 'http://chocolatey.org/install.ps1'
iex ((new-object net.webclient).DownloadString($url))
VerifyInstallation cinst
# Chocolatey sets the global path; set it for this shell too
$Env:Path += "$Env:ChocolateyInstall\bin"
# Install packages to C:\Bin so the root directory isn't polluted
cinst binroot
}
#-----------------------------------------------
# Git
#-----------------------------------------------
function InstallGit () {
$gitCmd = FindInRegistryPath git.exe
if ($gitCmd) {
write-host "Skipping git installation"
return
}
# Install the git package
cinst git
$gitCmd = VerifyInstallation git.exe --version
# Update path based on git installation mode
$gitDir = split-path -parent $gitCmd | split-path -parent
switch ($GIT_INSTALL_MODE) {
1 {
# => Use Git Bash only
# blank
}
2 {
# => Run Git from the Windows Command Prompt
AppendEnvAndGlobalPath "$gitDir\cmd" "User"
}
3 {
# => Run Git and included Unix tools from the Windows Command Prompt
AppendEnvAndGlobalPath "$gitDir\cmd" "User"
AppendEnvAndGlobalPath "$gitDir\bin" "User"
}
}
}
#-----------------------------------------------
# Vagrant
#-----------------------------------------------
function InstallVagrant () {
$vagrantCmd = FindInRegistryPath vagrant.bat
if ($vagrantCmd) {
write-host "Skipping vagrant installation"
return
}
# We need to pin a version of vagrant that plays nice with the Berkshelf plugin
cinst vagrant -version 1.4.3
VerifyInstallation vagrant.bat --version
}
function InstallVagrantPlugins () {
# Trying to run Vagrant from a directory that includes a Vagrantfile
# doesn't work so change to a directory that should not contain one
Push-Location "C:\"
# Berkshelf requires components that must be compiled with the Ruby DevKit
$vagrantCmd = FindInRegistryPathCheck vagrant.bat
Exec { &$vagrantCmd plugin install vagrant-omnibus }
Exec { &$vagrantCmd plugin install vagrant-berkshelf }
Exec { &$vagrantCmd plugin install vagrant-vbguest }
Pop-Location
}
#-----------------------------------------------
# Make virtual machine
#-----------------------------------------------
function InstallVirtualBox () {
if (FindInRegistryPath "VirtualBox") {
write-host "Skipping VirtualBox installation"
return
}
if (Test-Path "C:\Program Files\Oracle\VirtualBox\VirtualBox.exe") {
write-host "Skipping VirtualBox installation"
return
}
cinst virtualbox
}
function CloneLinuxVmRepository () {
# Create the development directory
if (! (Test-Path $DEVELOPMENT_DIRECTORY -pathType container) ) {
New-Item -ItemType directory -Path $DEVELOPMENT_DIRECTORY >$null
}
# Clone the repository
if (! (Test-Path "$DEVELOPMENT_DIRECTORY\linux-vm\" -pathType container) ) {
$gitCmd = FindInRegistryPathCheck git.exe
&$gitCmd clone https://github.com/webcoyote/linux-vm "$DEVELOPMENT_DIRECTORY\linux-vm"
if ($LASTEXITCODE -ne 0) {
write-host "ERROR: Unable to clone https://github.com/webcoyote/linux-vm"
exit 1
}
}
}
function MakeVirtualMachine () {
Push-Location "$DEVELOPMENT_DIRECTORY\linux-vm"
# Run Vagrant to bring up the VM
$vagrantCmd = FindInRegistryPathCheck vagrant.bat
Exec { &$vagrantCmd up --provider=virtualbox --provision }
# The virtual machine is now complete! But ...
# VirtualBox Guest Additions may not be up to date.
# To correct this use vagrant vbguest. My experience
# has been that it is necessary to be in graphics
# mode before upgrading and to reboot afterwards,
# otherwise the guest desktop does not resize properly
# when resizing its window on the host system.
# Switch to graphics mode
Exec { &$vagrantCmd ssh -c "sudo /sbin/init 5" -- -n -T }
# Update VirtualBox guest additions
write-host "Updating VirtualBox guest additions"
Exec { &$vagrantCmd vbguest --auto-reboot }
Pop-Location
}
#-----------------------------------------------
# Main
#-----------------------------------------------
InstallPackageManager
InstallGit
InstallVirtualBox
InstallVagrant
InstallVagrantPlugins
CloneLinuxVmRepository
MakeVirtualMachine
# Can I mention here how frequently PowerShell violates the principle of least surprise?
write-host @"
If you've just run this script for the first time you should exit this
command shell and start another so your PATH variable is set correctly.
"@