Skip to content

Commit dfeb1f1

Browse files
committed
init
0 parents  commit dfeb1f1

9 files changed

Lines changed: 1057 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packer-provisioner-windows-update*
2+
bindata.go

LICENSE.txt

Lines changed: 373 additions & 0 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
build: packer-provisioner-windows-update packer-provisioner-windows-update.exe
2+
3+
packer-provisioner-windows-update: *.go update/* update/bindata.go
4+
GOOS=linux GOARCH=amd64 go build -v -o $@
5+
6+
packer-provisioner-windows-update.exe: *.go update/* update/bindata.go
7+
GOOS=windows GOARCH=amd64 go build -v -o $@
8+
9+
update/bindata.go: update/*.ps1
10+
go-bindata -nocompress -ignore '\.go$$' -o $@ -prefix update -pkg update update
11+
12+
dist: build
13+
tar -czf packer-provisioner-windows-update-linux.tgz packer-provisioner-windows-update
14+
zip packer-provisioner-windows-update-windows.zip packer-provisioner-windows-update.exe
15+
16+
clean:
17+
rm -f packer-provisioner-windows-update* update/bindata.go
18+
19+
.PHONY: build dist clean

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Packer Windows Update Provisioner
2+
3+
[![Build status](https://ci.appveyor.com/api/projects/status/1bmqt9ywh82vhojt?svg=true)](https://ci.appveyor.com/project/rgl/packer-provisioner-windows-update)
4+
5+
This is a Packer plugin for installing Windows updates (akin to [rgl/vagrant-windows-update](https://github.com/rgl/vagrant-windows-update)).
6+
7+
**NB** This was only tested with Packer 1.0.0 and Windows Server 2016.
8+
9+
# Usage
10+
11+
[Download the binary from the releases page](https://github.com/rgl/packer-provisioner-windows-update/releases)
12+
and put it in the same directory as your `packer` executable.
13+
14+
Use the provisioner from your packer template file, e.g. like in [rgl/windows-2016-vagrant](https://github.com/rgl/windows-2016-vagrant):
15+
16+
```json
17+
{
18+
"provisioners": [
19+
{
20+
"type": "windows-update"
21+
}
22+
]
23+
}
24+
```
25+
26+
# Development
27+
28+
Install the dependencies:
29+
30+
```bash
31+
go get -u github.com/hashicorp/packer/packer/plugin
32+
go get -u github.com/masterzen/winrm
33+
go get -u github.com/jteeuwen/go-bindata/...
34+
```
35+
36+
Build:
37+
38+
```bash
39+
make
40+
```
41+
42+
Configure packer with the path to this provisioner by adding something like the
43+
following snippet to your `~/.packerconfig` (or `%APPDATA%/packer.config`):
44+
45+
```json
46+
{
47+
"provisioners": {
48+
"windows-update": "/home/rgl/Projects/packer-provisioner-windows-update/packer-provisioner-windows-update"
49+
}
50+
}
51+
```
52+
53+
If you are having problems running `packer` set the `PACKER_LOG=1` environment
54+
variable to see more information.

main.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package main
2+
3+
import (
4+
"github.com/hashicorp/packer/packer/plugin"
5+
6+
"./update"
7+
)
8+
9+
func main() {
10+
server, err := plugin.Server()
11+
if err != nil {
12+
panic(err)
13+
}
14+
server.RegisterProvisioner(new(update.Provisioner))
15+
server.Serve()
16+
}

update/elevated-template.ps1

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Set-StrictMode -Version Latest
2+
$ErrorActionPreference = 'Stop'
3+
$ProgressPreference = 'SilentlyContinue'
4+
trap {
5+
Write-Output "ERROR: $_"
6+
Write-Output (($_.ScriptStackTrace -split '\r?\n') -replace '^(.*)$','ERROR: $1')
7+
Write-Output (($_.Exception.ToString() -split '\r?\n') -replace '^(.*)$','ERROR EXCEPTION: $1')
8+
Exit 1
9+
}
10+
$name = "{{.TaskName}}"
11+
$log = "$env:SystemRoot\Temp\$name.out"
12+
$s = New-Object -ComObject "Schedule.Service"
13+
$s.Connect()
14+
$t = $s.NewTask($null)
15+
$t.XmlText = @'
16+
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
17+
<RegistrationInfo>
18+
<Description>{{.TaskDescription}}</Description>
19+
</RegistrationInfo>
20+
<Principals>
21+
<Principal id="Author">
22+
<UserId>{{.Username}}</UserId>
23+
<LogonType>Password</LogonType>
24+
<RunLevel>HighestAvailable</RunLevel>
25+
</Principal>
26+
</Principals>
27+
<Settings>
28+
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
29+
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
30+
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
31+
<AllowHardTerminate>true</AllowHardTerminate>
32+
<StartWhenAvailable>false</StartWhenAvailable>
33+
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
34+
<IdleSettings>
35+
<StopOnIdleEnd>false</StopOnIdleEnd>
36+
<RestartOnIdle>false</RestartOnIdle>
37+
</IdleSettings>
38+
<AllowStartOnDemand>true</AllowStartOnDemand>
39+
<Enabled>true</Enabled>
40+
<Hidden>false</Hidden>
41+
<RunOnlyIfIdle>false</RunOnlyIfIdle>
42+
<WakeToRun>false</WakeToRun>
43+
<ExecutionTimeLimit>PT24H</ExecutionTimeLimit>
44+
<Priority>4</Priority>
45+
</Settings>
46+
<Actions Context="Author">
47+
<Exec>
48+
<Command>cmd</Command>
49+
<Arguments>/c {{.Command}} &gt;%SYSTEMROOT%\Temp\{{.TaskName}}.out 2&gt;&amp;1</Arguments>
50+
</Exec>
51+
</Actions>
52+
</Task>
53+
'@
54+
$f = $s.GetFolder("\")
55+
$f.RegisterTaskDefinition($name, $t, 6, "{{.Username}}", "{{.Password}}", 1, $null) | Out-Null
56+
$t = $f.GetTask("\$name")
57+
$t.Run($null) | Out-Null
58+
$timeout = 10
59+
$sec = 0
60+
while ((!($t.state -eq 4)) -and ($sec -lt $timeout)) {
61+
Start-Sleep -s 1
62+
$sec++
63+
}
64+
$line = 0
65+
do {
66+
Start-Sleep -m 100
67+
if (Test-Path $log) {
68+
Get-Content $log | select -skip $line | ForEach {
69+
++$line
70+
Write-Output $_
71+
}
72+
}
73+
} while (!($t.state -eq 3))
74+
$result = $t.LastTaskResult
75+
if (Test-Path $log) {
76+
Remove-Item $log -Force -ErrorAction SilentlyContinue | Out-Null
77+
}
78+
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($s) | Out-Null
79+
exit $result

update/elevated.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// NB this code was based on https://github.com/hashicorp/packer/blob/370b67497e90785b71be1b6fcc6430de487d644e/provisioner/powershell/elevated.go
2+
3+
package update
4+
5+
import (
6+
"text/template"
7+
)
8+
9+
type elevatedOptions struct {
10+
Username string
11+
Password string
12+
TaskName string
13+
TaskDescription string
14+
Command string
15+
}
16+
17+
var elevatedTemplate = template.Must(
18+
template.New("Elevated").Parse(
19+
string(MustAsset("elevated-template.ps1"))))

0 commit comments

Comments
 (0)