Repository: rgl/packer-provisioner-windows-update
Branch: master
Commit: 632974b08f3c
Files: 27
Total size: 108.9 KB
Directory structure:
gitextract_5np1h6zz/
├── .devcontainer/
│ ├── Dockerfile
│ ├── devcontainer.json
│ ├── inputrc
│ ├── login.sh
│ └── setup.sh
├── .gitattributes
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .goreleaser.yml
├── .vscode/
│ └── settings.json
├── LICENSE.txt
├── Makefile
├── README.md
├── ci-release.sh
├── go.mod
├── go.sum
├── main.go
├── renovate.json5
├── renovate.sh
├── test.pkr.hcl
├── test.sh
└── update/
├── elevated-template.ps1
├── elevated.go
├── provisioner.go
├── provisioner.hcl2spec.go
├── update_ui.go
└── windows-update.ps1
================================================
FILE CONTENTS
================================================
================================================
FILE: .devcontainer/Dockerfile
================================================
# syntax=docker.io/docker/dockerfile:1.23
# see https://github.com/devcontainers/images/blob/main/src/base-debian/manifest.json
FROM mcr.microsoft.com/devcontainers/base:2.1.7-trixie
RUN <<'EOF'
#!/usr/bin/bash
set -euxo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get -y install --no-install-recommends \
bash-completion \
curl \
git \
openssh-client \
pylint \
python3-argcomplete \
python3-openssl \
python3-pip \
python3-venv \
python3-yaml \
qemu-system-x86 \
qemu-utils \
sudo \
unzip \
wget
apt-get clean
rm -rf /var/lib/apt/lists/*
activate-global-python-argcomplete
python3 -m venv --system-site-packages /opt/venv
EOF
ENV PATH="/opt/venv/bin:$PATH"
# disable the packer telemetry.
ENV CHECKPOINT_DISABLE=1
RUN <<'EOF'
#!/usr/bin/bash
set -euxo pipefail
# ensure /etc/profile is called at the top of the file, when running in a
# login shell.
sed -i '0,/esac/s/esac/&\n\nsource \/etc\/profile/' /home/vscode/.bashrc
EOF
COPY .devcontainer/inputrc /etc/inputrc
COPY .devcontainer/login.sh /etc/profile.d/login.sh
================================================
FILE: .devcontainer/devcontainer.json
================================================
{
"name": "Packer",
"dockerFile": "Dockerfile",
"context": "..",
"runArgs": [
"--group-add=108", // 108 is the id of the kvm group.
"-v=${localEnv:HOME}/.ssh/id_rsa:/home/vscode/.ssh/id_rsa:ro",
"-v=${localEnv:HOME}/.ssh/id_rsa.pub:/home/vscode/.ssh/id_rsa.pub:ro",
"-v=${localEnv:HOME}/.vagrant.d:/home/vscode/.vagrant.d:ro",
"-v=/usr/share/ovmf:/usr/share/ovmf:ro",
"--device=/dev/kvm"
],
"postCreateCommand": "bash .devcontainer/setup.sh",
"features": {
"ghcr.io/devcontainers/features/go:1": {
"version": "1.26.1"
},
"ghcr.io/devcontainers-extra/features/packer-asdf:2": {
"version": "1.15.1"
}
},
"customizations": {
"vscode": {
"extensions": [
"hashicorp.hcl",
"streetsidesoftware.code-spell-checker"
]
}
}
}
================================================
FILE: .devcontainer/inputrc
================================================
set input-meta on
set output-meta on
set show-all-if-ambiguous on
set completion-ignore-case on
"\e[A": history-search-backward
"\e[B": history-search-forward
"\eOD": backward-word
"\eOC": forward-word
================================================
FILE: .devcontainer/login.sh
================================================
export EDITOR=code
export PAGER=less
alias l='ls -lF --color'
alias ll='l -a'
alias h='history 25'
alias j='jobs -l'
================================================
FILE: .devcontainer/setup.sh
================================================
#!/bin/bash
set -euxo pipefail
pushd /home/vscode
sudo chown vscode:vscode .ssh && sudo chmod 700 .ssh
popd
================================================
FILE: .gitattributes
================================================
/update/*.ps1 -text
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on: [push, pull_request]
jobs:
build:
name: Build
runs-on: windows-2022
steps:
- name: Configure git
run: git config --global core.autocrlf false
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.26.1'
- name: Set up msys2
uses: msys2/setup-msys2@v2
with:
install: make tar zip unzip
path-type: inherit
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
run: msys2 ./ci-release.sh
- name: Archive
uses: actions/upload-artifact@v7
with:
name: artifacts
path: |
dist/
!dist/*/*
================================================
FILE: .gitignore
================================================
dist/
packer-plugin-windows-update
packer-plugin-windows-update.exe
tmp*
.idea/
output-*/
*.log
================================================
FILE: .goreleaser.yml
================================================
version: 2
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
flags:
- -v
- -trimpath
ldflags:
- -s
- -w
- -X main.version={{ .Version }}
- -X main.commit={{ .Commit }}
- -X main.date={{ .CommitDate }}
mod_timestamp: '{{ .CommitTimestamp }}'
binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
snapshot:
version_template: '{{ .Version }}-SNAPSHOT-{{ .ShortCommit }}'
release:
draft: true
prerelease: auto
archives:
- formats:
- zip
name_template: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
checksum:
name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS'
algorithm: sha256
signs:
- artifacts: checksum
args:
- --batch
- --local-user
- "{{ .Env.GPG_FINGERPRINT }}"
- --output
- ${signature}
- --detach-sign
- ${artifact}
================================================
FILE: .vscode/settings.json
================================================
{
"cSpell.words": [
"devcontainers"
]
}
================================================
FILE: LICENSE.txt
================================================
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
================================================
FILE: Makefile
================================================
GOPATH := $(shell go env GOPATH | tr '\\' '/')
GOEXE := $(shell go env GOEXE)
GOHOSTOS := $(shell go env GOHOSTOS)
GOHOSTARCH := $(shell go env GOHOSTARCH)
GOHOSTARCHVERSION := $(shell go env "GO$(shell go env GOHOSTARCH | tr '[:lower:]' '[:upper:]')")
GORELEASER := $(GOPATH)/bin/goreleaser
SOURCE_FILES := *.go update/* update/provisioner.hcl2spec.go
PLUGIN_PATH := dist/packer-plugin-windows-update_$(GOHOSTOS)_$(GOHOSTARCH)_$(GOHOSTARCHVERSION)/packer-plugin-windows-update_*_$(GOHOSTOS)_$(GOHOSTARCH)$(GOEXE)
# see https://github.com/goreleaser/goreleaser
# renovate: datasource=github-releases depName=goreleaser/goreleaser extractVersion=^v?(?<version>2\..+)
GORELEASER_VERSION := 2.15.2
all: clean build
init:
go mod download
$(GORELEASER):
go install github.com/goreleaser/goreleaser/v2@v$(GORELEASER_VERSION)
build: init $(GORELEASER) $(SOURCE_FILES)
API_VERSION="$(shell go run . describe 2>/dev/null | jq -r .api_version)" \
$(GORELEASER) build --skip=validate --clean --single-target
release-snapshot: init $(GORELEASER) $(SOURCE_FILES)
API_VERSION="$(shell go run . describe 2>/dev/null | jq -r .api_version)" \
$(GORELEASER) release --snapshot --skip=publish --clean
release: init $(GORELEASER) $(SOURCE_FILES)
API_VERSION="$(shell go run . describe 2>/dev/null | jq -r .api_version)" \
$(GORELEASER) release --clean
# see https://www.packer.io/guides/hcl/component-object-spec/
update/provisioner.hcl2spec.go: update/provisioner.go
go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@$(shell go list -m -f '{{.Version}}' github.com/hashicorp/packer-plugin-sdk)
go generate ./...
clean:
rm -rf update/provisioner.hcl2spec.go dist tmp* output-test *.log
test: build
./test.sh
.PHONY: all init build release release-snapshot install uninstall clean test
================================================
FILE: README.md
================================================
# Packer Windows Update Provisioner
[](https://github.com/rgl/packer-plugin-windows-update/actions?query=workflow%3ABuild)
This is a Packer plugin for installing Windows updates (akin to [rgl/vagrant-windows-update](https://github.com/rgl/vagrant-windows-update)).
**NB** This was only tested with Packer 1.15.1 and the images at [rgl/windows-vagrant](https://github.com/rgl/windows-vagrant), so YMMV.
# Usage
Configure your packer template to require a [release version of the plugin](https://github.com/rgl/packer-plugin-windows-update/releases), e.g.:
```hcl
packer {
required_plugins {
windows-update = {
version = "0.18.1"
source = "github.com/rgl/windows-update"
}
}
}
```
Initialize your packer template (it will install the plugin):
```bash
packer init your-template.pkr.hcl
```
Use this provisioner plugin from your packer template file, e.g. like in [rgl/windows-vagrant](https://github.com/rgl/windows-vagrant):
```hcl
build {
provisioner "windows-update" {
filters = [
# exclude KB5007651:
# Update for Windows Security platform - KB5007651 (Version 10.0.29510.1001)
# NB it can only be applied while the user is logged in.
"exclude:$_.Title -like '*KB5007651*'",
"include:$true",
]
}
}
```
Note, the plugin automatically restarts the machine after Windows Updates are applied and repeats until all updates are installed. The reboots occur similar to the windows-restart provisioner built into packer where packer is aware that a shutdown is in progress.
## Search Criteria, Filters and Update Limit
You can select which Windows Updates are installed by defining the search criteria, a set of filters, and how many updates are installed at a time.
Normally you would use one of the following settings:
| Name | `search_criteria` | `filters` |
|---------------|---------------------------------------------|-----------------|
| Important | `AutoSelectOnWebSites=1 and IsInstalled=0` | `$true` |
| Recommended | `BrowseOnly=0 and IsInstalled=0` | `$true` |
| All | `IsInstalled=0` | `$true` |
| Optional Only | `AutoSelectOnWebSites=0 and IsInstalled=0` | `$_.BrowseOnly` |
**NB** `Recommended` is the default setting.
But you can customize them, e.g.:
```hcl
build {
provisioner "windows-update" {
search_criteria = "IsInstalled=0"
filters = [
"exclude:$_.Title -like '*Preview*'",
"include:$true",
]
update_limit = 25
}
}
```
**NB** For more information about the search criteria see the [IUpdateSearcher::Search method](https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-search) documentation and the [xWindowsUpdateAgent DSC resource source](https://github.com/dsccommunity/xWindowsUpdate/tree/master/source/DSCResources/MSFT_xWindowsUpdateAgent).
**NB** If the `update_limit` attribute is not declared, it defaults to `1000`.
The general filter syntax is:
ACTION:EXPRESSION
`ACTION` is a string that can have one of the following values:
| action | description |
| --------- | ------------------------------------------------------------ |
| `include` | includes the update when the expression evaluates to `$true` |
| `exclude` | excludes the update when the expression evaluates to `$true` |
**NB** If no `ACTION` evaluates to `$true` the update will **NOT** be installed.
`EXPRESSION` is a PowerShell expression. When it returns `$true`, the
`ACTION` is executed and no further filters are evaluated.
Inside an expression, the Windows Update [IUpdate interface](https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdate) can be referenced by the `$_` variable.
# Development
Install the dependencies:
* [Docker](https://docs.docker.com/engine/install/).
* [Visual Studio Code](https://code.visualstudio.com).
* [Dev Container plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
* [`windows-2022-amd64` vagrant box](https://github.com/rgl/windows-vagrant).
Open this directory with the Dev Container plugin.
Open `bash` inside the Visual Studio Code Terminal.
Build:
```bash
make
```
Test with QEMU:
```bash
make test
```
================================================
FILE: ci-release.sh
================================================
#!/bin/bash
set -euxo pipefail
# ensure provisioner.hcl2spec.go is updated by re-generate it. if there are
# differences, abort the build.
rm -f update/provisioner.hcl2spec.go
make update/provisioner.hcl2spec.go
git diff --exit-code update/provisioner.hcl2spec.go \
|| (echo 'ERROR: You must re-generate update/provisioner.hcl2spec.go and commit the changes.' && exit 1)
# point the msys2 user gpg home to the one managed by the crazy-max/ghaction-import-gpg github action.
ln -s /c/Users/runneradmin/.gnupg ~/.gnupg
# do the release.
if [[ $GITHUB_REF == refs/tags/v* ]]; then
make release
else
make release-snapshot
fi
================================================
FILE: go.mod
================================================
module github.com/rgl/packer-plugin-windows-update
go 1.26.1
require (
github.com/hashicorp/hcl/v2 v2.24.0
github.com/hashicorp/packer-plugin-sdk v0.6.7
github.com/zclconf/go-cty v1.18.0
)
require (
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect
github.com/aws/aws-sdk-go-v2/config v1.32.14 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.19.14 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.5 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 // indirect
github.com/aws/smithy-go v1.24.3 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/consul/api v1.33.7 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter/v2 v2.2.3 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.4 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
github.com/hashicorp/go-version v1.9.0 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
github.com/hashicorp/serf v0.10.2 // indirect
github.com/hashicorp/vault/api v1.23.0 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/klauspost/compress v1.18.5 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/iochan v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
github.com/ulikunitz/xz v0.5.15 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect
golang.org/x/mod v0.34.0 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.43.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
)
replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187
================================================
FILE: go.sum
================================================
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
github.com/aws/aws-sdk-go-v2/config v1.32.14 h1:opVIRo/ZbbI8OIqSOKmpFaY7IwfFUOCCXBsUpJOwDdI=
github.com/aws/aws-sdk-go-v2/config v1.32.14/go.mod h1:U4/V0uKxh0Tl5sxmCBZ3AecYny4UNlVmObYjKuuaiOo=
github.com/aws/aws-sdk-go-v2/credentials v1.19.14 h1:n+UcGWAIZHkXzYt87uMFBv/l8THYELoX6gVcUvgl6fI=
github.com/aws/aws-sdk-go-v2/credentials v1.19.14/go.mod h1:cJKuyWB59Mqi0jM3nFYQRmnHVQIcgoxjEMAbLkpr62w=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 h1:NUS3K4BTDArQqNu2ih7yeDLaS3bmHD0YndtA6UP884g=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21/go.mod h1:YWNWJQNjKigKY1RHVJCuupeWDrrHjRqHm0N9rdrWzYI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.5 h1:z2ayoK3pOvf8ODj/vPR0FgAS5ONruBq0F94SRoW/BIU=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.5/go.mod h1:mpZB5HAl4ZIISod9qCi12xZ170TbHX9CCJV5y7nb7QU=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 h1:QKZH0S178gCmFEgst8hN0mCX1KxLgHBKKY/CLqwP8lg=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9/go.mod h1:7yuQJoT+OoH8aqIxw9vwF+8KpvLZ8AWmvmUWHsGQZvI=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 h1:lFd1+ZSEYJZYvv9d6kXzhkZu07si3f+GQ1AaYwa2LUM=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.15/go.mod h1:WSvS1NLr7JaPunCXqpJnWk1Bjo7IxzZXrZi1QQCkuqM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 h1:dzztQ1YmfPrxdrOiuZRMF6fuOwWlWpD2StNLTceKpys=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19/go.mod h1:YO8TrYtFdl5w/4vmjL8zaBSsiNp3w0L1FfKVKenZT7w=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 h1:p8ogvvLugcR/zLBXTXrTkj0RYBUdErbMnAFFp12Lm/U=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10/go.mod h1:60dv0eZJfeVXfbT1tFJinbHrDfSJ2GZl4Q//OSSNAVw=
github.com/aws/smithy-go v1.24.3 h1:XgOAaUgx+HhVBoP4v8n6HCQoTRDhoMghKqw4LNHsDNg=
github.com/aws/smithy-go v1.24.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/consul/api v1.33.7 h1:apLZVzX7O7BLgHyh4pvczcsBzPmYSVXGKZQbOaA1ae0=
github.com/hashicorp/consul/api v1.33.7/go.mod h1:SjR3cjwCUSLLDfVw5dFg76rnnKjOySxr8W8lC5s01C8=
github.com/hashicorp/consul/sdk v0.17.3 h1:oZMMxzQGSsiT+ToOH50y3Qcs0nc9Ud+7L5lRx+EmMU0=
github.com/hashicorp/consul/sdk v0.17.3/go.mod h1:jnOmYjiNfVRpBaujQ1DFFVs0N6g3S1y6wygSjLTzYfc=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter/v2 v2.2.3 h1:6CVzhT0KJQHqd9b0pK3xSP0CM/Cv+bVhk+jcaRJ2pGk=
github.com/hashicorp/go-getter/v2 v2.2.3/go.mod h1:hp5Yy0GMQvwWVUmwLs3ygivz1JSLI323hdIE9J9m7TY=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6elejKY=
github.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI=
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0=
github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE=
github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM=
github.com/hashicorp/memberlist v0.5.2 h1:rJoNPWZ0juJBgqn48gjy59K5H4rNgvUoM1kUD7bXiuI=
github.com/hashicorp/memberlist v0.5.2/go.mod h1:Ri9p/tRShbjYnpNf4FFPXG7wxEGY4Nrcn6E7jrVa//4=
github.com/hashicorp/packer-plugin-sdk v0.6.7 h1:R6xO8j5GUT1AC+1CmDvXCjjiCDndWbIA1O7jJ3MeTVs=
github.com/hashicorp/packer-plugin-sdk v0.6.7/go.mod h1:J+hZE+SdN0MPCZLmoRPSrqg4YuP/mXTuuVqiAYbDVfw=
github.com/hashicorp/serf v0.10.2 h1:m5IORhuNSjaxeljg5DeQVDlQyVkhRIjJDimbkCa8aAc=
github.com/hashicorp/serf v0.10.2/go.mod h1:T1CmSGfSeGfnfNy/w0odXQUR1rfECGd2Qdsp84DjOiY=
github.com/hashicorp/vault/api v1.23.0 h1:gXgluBsSECfRWTSW9niY2jwg2e9mMJc4WoHNv4g3h6A=
github.com/hashicorp/vault/api v1.23.0/go.mod h1:zransKiB9ftp+kgY8ydjnvCU7Wk8i9L0DYWpXeMj9ko=
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nywilken/go-cty v1.13.3 h1:03U99oXf3j3g9xgqAE3YGpixCjM8Mg09KZ0Ji9LzX0o=
github.com/nywilken/go-cty v1.13.3/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA=
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ=
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
================================================
FILE: main.go
================================================
package main
import (
"log"
"github.com/hashicorp/packer-plugin-sdk/plugin"
v "github.com/hashicorp/packer-plugin-sdk/version"
"github.com/rgl/packer-plugin-windows-update/update"
)
var (
version = "0.0.0"
commit = "unknown"
date = "unknown"
)
func main() {
log.Printf("Starting packer-plugin-windows-update (version %s; commit %s; date %s)", version, commit, date)
pps := plugin.NewSet()
pps.RegisterProvisioner(plugin.DEFAULT_NAME, new(update.Provisioner))
pps.SetVersion(v.InitializePluginVersion(version, ""))
err := pps.Run()
if err != nil {
log.Fatalf("Failed to start: %v", err)
}
}
================================================
FILE: renovate.json5
================================================
// see https://docs.renovatebot.com/templates/
// see https://docs.renovatebot.com/modules/manager/
// see https://docs.renovatebot.com/modules/manager/regex/
// see https://docs.renovatebot.com/configuration-options/
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"regexManagers": [
// default datasources.
{
"fileMatch": [
"\\.yml$",
"\\.sh$",
"Makefile",
],
"matchStrings": [
"# renovate: datasource=(?<datasource>[^:]+?) depName=(?<depName>.+?)( versioning=(?<versioning>.+?))?( extractVersion=(?<extractVersion>.+?))?( registryUrl=(?<registryUrl>.+?))?\\s.+?(:=|:|=)\\s*[\"']?(?<currentValue>.+?)[\"']?\\s"
],
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver-coerced{{/if}}",
"extractVersionTemplate": "{{#if extractVersion}}{{{extractVersion}}}{{else}}^v?(?<version>.+)${{/if}}"
},
// nuget:powershellgallery datasource.
{
"fileMatch": [
"\\.yml$",
"\\.sh$",
"Makefile",
],
"matchStrings": [
"# renovate: datasource=(?<datasource>nuget):powershellgallery depName=(?<depName>.+?)( versioning=(?<versioning>.+?))?( extractVersion=(?<extractVersion>.+?))?( registryUrl=(?<registryUrl>.+?))?\\s.+?(:=|:|=)\\s*[\"']?(?<currentValue>.+?)[\"']?\\s"
],
"registryUrlTemplate": "{{#if registryUrl}}{{{registryUrl}}}{{else}}https://www.powershellgallery.com/api/v2{{/if}}",
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}nuget{{/if}}",
"extractVersionTemplate": "{{#if extractVersion}}{{{extractVersion}}}{{else}}^v?(?<version>.+)${{/if}}"
}
]
}
================================================
FILE: renovate.sh
================================================
#!/bin/bash
set -euo pipefail
# this executes renovate against the local repository.
# NB this uses a temporary gitea instance because running renovate against a
# local directory not (yet?) supported.
# see https://github.com/renovatebot/renovate/issues/3609
export RENOVATE_USERNAME='renovate'
export RENOVATE_NAME='Renovate Bot'
export RENOVATE_PASSWORD='password'
gitea_container_name="$(basename "$(dirname "$(realpath "${BASH_SOURCE[0]}")")")-renovate-gitea"
# see https://hub.docker.com/r/gitea/gitea/tags
# renovate: datasource=docker depName=gitea/gitea
gitea_version='1.25.5'
# see https://hub.docker.com/r/renovate/renovate/tags
# see https://github.com/renovatebot/renovate/releases
# renovate: datasource=docker depName=renovate/renovate
renovate_version='43.104.1'
# clean.
echo 'Deleting existing Gitea...'
docker rm --force "$gitea_container_name" >/dev/null 2>&1
echo 'Deleting existing temporary files...'
rm -f tmp/renovate-*
install -d tmp
# start gitea in background.
# see https://docs.gitea.io/en-us/config-cheat-sheet/
# see https://github.com/go-gitea/gitea/releases
# see https://github.com/go-gitea/gitea/blob/v1.25.5/docker/root/etc/s6/gitea/setup
echo 'Starting Gitea...'
docker run \
--detach \
--name "$gitea_container_name" \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
-e SECRET_KEY=opensesame \
-p 3000 \
"gitea/gitea:$gitea_version" \
>/dev/null
gitea_addr="$(docker port "$gitea_container_name" 3000 | head -1)"
gitea_url="http://$gitea_addr"
export RENOVATE_ENDPOINT="$gitea_url"
export GIT_PUSH_REPOSITORY="http://$RENOVATE_USERNAME:$RENOVATE_PASSWORD@$gitea_addr/$RENOVATE_USERNAME/test.git"
# wait for gitea to be ready.
echo "Waiting for Gitea to be ready at $gitea_url..."
GITEA_URL="$gitea_url" bash -euc 'while [ -z "$(wget -qO- "$GITEA_URL/api/v1/version" | jq -r ".version | select(.!=null)")" ]; do sleep 5; done'
# create user in gitea.
echo "Creating Gitea $RENOVATE_USERNAME user..."
docker exec --user git "$gitea_container_name" gitea admin user create \
--admin \
--email "$RENOVATE_USERNAME@example.com" \
--username "$RENOVATE_USERNAME" \
--password "$RENOVATE_PASSWORD"
curl \
--silent \
--show-error \
--fail-with-body \
-u "$RENOVATE_USERNAME:$RENOVATE_PASSWORD" \
-X 'PATCH' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d "{\"full_name\":\"$RENOVATE_NAME\"}" \
"$gitea_url/api/v1/user/settings" \
| jq \
> /dev/null
# create the user personal access token.
# see https://docs.gitea.io/en-us/api-usage/
# see https://docs.gitea.io/en-us/oauth2-provider/#scopes
# see https://try.gitea.io/api/swagger#/user/userCreateToken
echo "Creating Gitea $RENOVATE_USERNAME user personal access token..."
curl \
--silent \
--show-error \
--fail-with-body \
-u "$RENOVATE_USERNAME:$RENOVATE_PASSWORD" \
-X POST \
-H "Content-Type: application/json" \
-d '{"name": "renovate", "scopes": ["read:user", "write:issue", "write:repository"]}' \
"$gitea_url/api/v1/users/$RENOVATE_USERNAME/tokens" \
| jq -r .sha1 \
>tmp/renovate-gitea-token.txt
# try the token.
echo "Trying the Gitea $RENOVATE_USERNAME user personal access token..."
RENOVATE_TOKEN="$(cat tmp/renovate-gitea-token.txt)"
export RENOVATE_TOKEN
curl \
--silent \
--show-error \
--fail-with-body \
-H "Authorization: token $RENOVATE_TOKEN" \
-H 'Accept: application/json' \
"$gitea_url/api/v1/version" \
| jq \
> /dev/null
# create remote repository in gitea.
echo "Creating Gitea $RENOVATE_USERNAME test repository..."
curl \
--silent \
--show-error \
--fail-with-body \
-u "$RENOVATE_USERNAME:$RENOVATE_PASSWORD" \
-X POST \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "test"}' \
"$gitea_url/api/v1/user/repos" \
| jq \
> /dev/null
# push the code to local gitea repository.
# NB running renovate locally is not yet supported.
# see https://github.com/renovatebot/renovate/issues/3609
echo "Pushing local repository to Gitea $RENOVATE_USERNAME test repository..."
git push --force "$GIT_PUSH_REPOSITORY"
# see https://docs.renovatebot.com/modules/platform/gitea/
# see https://docs.renovatebot.com/self-hosted-configuration/#dryrun
# see https://github.com/renovatebot/renovate/blob/main/docs/usage/examples/self-hosting.md
# see https://github.com/renovatebot/renovate/tree/main/lib/modules/datasource
# see https://github.com/renovatebot/renovate/tree/main/lib/modules/versioning
RENOVATE_TOKEN="$(cat tmp/renovate-gitea-token.txt)"
export RENOVATE_TOKEN
# NB these can also be passed as raw positional arguments to docker run.
export RENOVATE_REPOSITORIES="$RENOVATE_USERNAME/test"
# see https://docs.github.com/en/rest/rate-limit#get-rate-limit-status-for-the-authenticated-user
# see https://github.com/settings/tokens
# NB this is only used for authentication. the token should not have any scope enabled.
#export GITHUB_COM_TOKEN='TODO-YOUR-TOKEN'
# let renovate create all the required pull requests.
# see https://docs.renovatebot.com/configuration-options/#prhourlylimit
# see https://docs.renovatebot.com/configuration-options/#prconcurrentlimit
export RENOVATE_PR_HOURLY_LIMIT='0'
export RENOVATE_PR_CONCURRENT_LIMIT='0'
echo 'Running renovate...'
# NB to capture the traffic using mitmproxy, start mitmweb in a different
# shell, then enable the following if (i.e. true).
docker_extra_args=()
if false; then
docker_extra_args+=(
--env http_proxy=http://127.0.0.1:8080
--env https_proxy=http://127.0.0.1:8080
--env no_proxy=
--env SSL_CERT_FILE=/usr/local/shared/ca-certificates/mitmproxy-ca.crt
--volume "$HOME/.mitmproxy/mitmproxy-ca-cert.pem:/usr/local/shared/ca-certificates/mitmproxy-ca.crt:ro"
)
fi
# NB use --dry-run=lookup for not modifying the repository (e.g. for not
# creating pull requests).
docker run \
--rm \
--tty \
--interactive \
--net host \
--env GITHUB_COM_TOKEN \
--env RENOVATE_ENDPOINT \
--env RENOVATE_TOKEN \
--env RENOVATE_REPOSITORIES \
--env RENOVATE_PR_HOURLY_LIMIT \
--env RENOVATE_PR_CONCURRENT_LIMIT \
--env LOG_LEVEL=debug \
--env LOG_FORMAT=json \
"${docker_extra_args[@]}" \
"renovate/renovate:$renovate_version" \
--platform=gitea \
--git-url=endpoint \
>tmp/renovate-log.txt
grep -E '^{' \
tmp/renovate-log.txt \
>tmp/renovate-log.json
echo 'Getting results...'
# extract the errors.
jq 'select(.err)' tmp/renovate-log.json >tmp/renovate-errors.json
# extract the result from the renovate log.
jq 'select(.msg == "packageFiles with updates") | .config' tmp/renovate-log.json >tmp/renovate-result.json
# extract all the dependencies.
jq 'to_entries[].value[] | {packageFile,dep:.deps[]}' tmp/renovate-result.json >tmp/renovate-dependencies.json
# extract the dependencies that have updates.
jq 'select((.dep.updates | length) > 0)' tmp/renovate-dependencies.json >tmp/renovate-dependencies-updates.json
# helpers.
function show-title {
echo
echo '#'
echo "# $1"
echo '#'
echo
}
# show errors.
if [ "$(jq --slurp length tmp/renovate-errors.json)" -ne '0' ]; then
show-title errors
jq . tmp/renovate-errors.json
fi
# show dependencies.
function show-dependencies {
show-title "$1"
(
printf 'packageFile\tdatasource\tdepName\tcurrentValue\tnewVersions\tskipReason\twarnings\n'
jq \
-r \
'[
.packageFile,
.dep.datasource,
.dep.depName,
.dep.currentValue,
(.dep | select(.updates) | .updates | map(.newVersion) | join(" | ")),
.dep.skipReason,
(.dep | select(.warnings) | .warnings | map(.message) | join(" | "))
] | @tsv' \
"$2" \
| sort
) | column -t -s "$(printf \\t)"
}
show-dependencies 'Dependencies' tmp/renovate-dependencies.json
show-dependencies 'Dependencies Updates' tmp/renovate-dependencies-updates.json
# show the gitea project.
show-title "See PRs at $gitea_url/$RENOVATE_USERNAME/test/pulls (you can login as $RENOVATE_USERNAME:$RENOVATE_PASSWORD)"
================================================
FILE: test.pkr.hcl
================================================
packer {
required_plugins {
# see https://github.com/hashicorp/packer-plugin-qemu
qemu = {
version = "1.1.4"
source = "github.com/hashicorp/qemu"
}
# see https://github.com/rgl/packer-plugin-windows-update
windows-update = {
version = ">= 0.0.0"
source = "github.com/rgl/windows-update"
}
}
}
variable "disk_size" {
type = string
default = "61440"
}
variable "disk_image" {
type = string
}
source "qemu" "test" {
headless = true
accelerator = "kvm"
machine_type = "q35"
cpus = 2
memory = 4096
qemuargs = [
strcontains(var.disk_image, "uefi") ? ["-bios", "/usr/share/ovmf/OVMF.fd"] : null,
["-cpu", "host"],
]
disk_interface = "virtio-scsi"
disk_cache = "unsafe"
disk_discard = "unmap"
disk_image = true
use_backing_file = true
disk_size = var.disk_size
iso_url = var.disk_image
iso_checksum = "none"
net_device = "virtio-net"
shutdown_command = "shutdown /s /t 0 /f /d p:4:1 /c \"Packer Shutdown\""
communicator = "winrm"
winrm_username = "vagrant"
winrm_password = "vagrant"
winrm_timeout = "4h"
}
build {
sources = [
"source.qemu.test",
]
provisioner "windows-update" {
}
provisioner "powershell" {
use_pwsh = true
inline = [
<<-EOF
$p = 'c:/packer.delete.me.to.end.test.wait.txt'
Set-Content $p 'delete this file to end the packer test wait'
Write-Host "ATTENTION To end this test wait, login into the machine and delete the $p file. Or just press Ctrl+C."
while (Test-Path $p) {
Start-Sleep -Seconds 5
}
EOF
]
}
}
================================================
FILE: test.sh
================================================
#!/usr/bin/bash
set -euo pipefail
GOHOSTOS="$(go env GOHOSTOS)"
GOHOSTARCH="$(go env GOHOSTARCH)"
PLUGIN_PATH="$(
jq -r \
--arg goos "$GOHOSTOS" \
--arg goarch "$GOHOSTARCH" \
'.[] | select(.goos == $goos and .goarch == $goarch and .extra.ID == "packer-plugin-windows-update") | .path' \
dist/artifacts.json)"
PLUGIN_BASE_NAME="$(basename "$PLUGIN_PATH")"
PLUGIN_TEST_PATH="dist/test/plugins/github.com/rgl/windows-update/$PLUGIN_BASE_NAME"
# see https://developer.hashicorp.com/packer/docs/plugins/creation/plugin-load-spec
rm -rf output-test test.log dist/test
install -d dist/test/plugins/github.com/rgl/windows-update
install "$PLUGIN_PATH" "$PLUGIN_TEST_PATH"
(cd "$(dirname "$PLUGIN_TEST_PATH")" && \
sha256sum "$PLUGIN_BASE_NAME" >"${PLUGIN_BASE_NAME}_SHA256SUM")
export CHECKPOINT_DISABLE=1
export PACKER_LOG=1
export PACKER_LOG_PATH=test.log
export PACKER_CONFIG_DIR="$PWD/dist/test"
export PACKER_PLUGIN_PATH="$PWD/dist/test/plugins"
#export PKR_VAR_disk_image=~/.vagrant.d/boxes/windows-11-24h2-amd64/0.0.0/libvirt/box_0.img
#export PKR_VAR_disk_image=~/.vagrant.d/boxes/windows-2022-amd64/0.0.0/libvirt/box_0.img
#export PKR_VAR_disk_image=~/.vagrant.d/boxes/windows-2025-amd64/0.0.0/libvirt/box_0.img
#export PKR_VAR_disk_image=~/.vagrant.d/boxes/windows-11-24h2-uefi-amd64/0.0.0/libvirt/box_0.img
export PKR_VAR_disk_image=~/.vagrant.d/boxes/windows-2022-uefi-amd64/0.0.0/libvirt/box_0.img
#export PKR_VAR_disk_image=~/.vagrant.d/boxes/windows-2025-uefi-amd64/0.0.0/libvirt/box_0.img
packer init -only=qemu.test test.pkr.hcl
packer build -only=qemu.test -on-error=abort test.pkr.hcl
================================================
FILE: update/elevated-template.ps1
================================================
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
trap {
Write-Output "ERROR: $_"
Write-Output (($_.ScriptStackTrace -split '\r?\n') -replace '^(.*)$','ERROR: $1')
Write-Output (($_.Exception.ToString() -split '\r?\n') -replace '^(.*)$','ERROR EXCEPTION: $1')
Exit 1
}
$name = "{{.TaskName}}"
$log = "$env:SystemRoot\Temp\$name.out"
$s = New-Object -ComObject "Schedule.Service"
$s.Connect()
$t = $s.NewTask($null)
$t.XmlText = @'
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Description>{{.TaskDescription}}</Description>
</RegistrationInfo>
<Principals>
<Principal id="Author">
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>false</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT24H</ExecutionTimeLimit>
<Priority>4</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>cmd</Command>
<Arguments>/c {{.Command}} >%SYSTEMROOT%\Temp\{{.TaskName}}.out 2>&1</Arguments>
</Exec>
</Actions>
</Task>
'@
$username = "{{.Username}}"
$password = "{{.Password}}"
if (!$password) {
$password = $null
}
$f = $s.GetFolder("\")
$f.RegisterTaskDefinition($name, $t, 6, $username, $password, 1, $null) | Out-Null
$t = $f.GetTask("\$name")
$t.Run($null) | Out-Null
$timeout = 10
$sec = 0
while ((!($t.state -eq 4)) -and ($sec -lt $timeout)) {
Start-Sleep -Seconds 1
$sec++
}
# Windows PowerShell 2 on Windows 7 does not have Get-CimInstance.
# PowerShell 6 does not have Get-WmiObject.
if (!(Get-Command Get-CimInstance -ErrorAction:SilentlyContinue)) {
function Get-CimInstance {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True, Position = 0)]
[string]
$ClassName
)
Get-WmiObject -Class $ClassName
}
}
$reportProgressInterval = New-TimeSpan -Minutes 1
$startDate = Get-Date
$line = 0
do {
Start-Sleep -Seconds 5
if (Test-Path $log) {
Get-Content $log | Select-Object -skip $line | ForEach-Object {
++$line
Write-Output $_
}
}
$currentDate = Get-Date
if ($currentDate.Subtract($startDate) -ge $reportProgressInterval) {
$startDate = $currentDate
$cpuUsage = (Get-CimInstance CIM_Processor | Measure-Object -Property LoadPercentage -Average).Average / 100
$os = Get-CimInstance Win32_OperatingSystem
$memoryUsage = 1 - $os.FreePhysicalMemory / $os.TotalVisibleMemorySize
Write-Output ("Waiting for operation to complete (system performance: {0:P0} cpu; {1:P0} memory)..." -f $cpuUsage,$memoryUsage)
}
} while (!($t.state -eq 3))
$result = $t.LastTaskResult
if (Test-Path $log) {
Remove-Item $log -Force -ErrorAction SilentlyContinue | Out-Null
}
# delete scheduled task
$f.DeleteTask("\$name", 0)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($s) | Out-Null
exit $result
================================================
FILE: update/elevated.go
================================================
// NB this code was based on https://github.com/hashicorp/packer/blob/370b67497e90785b71be1b6fcc6430de487d644e/provisioner/powershell/elevated.go
package update
import (
_ "embed" // this is needed for using the go:embed directive
"text/template"
)
type elevatedOptions struct {
Username string
Password string
TaskName string
TaskDescription string
Command string
}
//go:embed elevated-template.ps1
var elevatedTemplatePs1 string
var elevatedTemplate = template.Must(
template.New("Elevated").Parse(
elevatedTemplatePs1))
================================================
FILE: update/provisioner.go
================================================
//go:generate packer-sdc mapstructure-to-hcl2 -type Config
// NB this code was based on https://github.com/hashicorp/packer/blob/81522dced0b25084a824e79efda02483b12dc7cd/provisioner/windows-restart/provisioner.go
package update
import (
"bytes"
"context"
_ "embed" // this is needed for using the go:embed directive
"encoding/base64"
"errors"
"fmt"
"strings"
"time"
"unicode/utf16"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer-plugin-sdk/common"
"github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/hashicorp/packer-plugin-sdk/retry"
"github.com/hashicorp/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer-plugin-sdk/uuid"
)
const (
elevatedPath = "C:/Windows/Temp/packer-windows-update-elevated.ps1"
elevatedCommand = "PowerShell -ExecutionPolicy Bypass -OutputFormat Text -File C:/Windows/Temp/packer-windows-update-elevated.ps1"
windowsUpdatePath = "C:/Windows/Temp/packer-windows-update.ps1"
pendingRebootElevatedPath = "C:/Windows/Temp/packer-windows-update-pending-reboot-elevated.ps1"
pendingRebootElevatedCommand = "PowerShell -ExecutionPolicy Bypass -OutputFormat Text -File C:/Windows/Temp/packer-windows-update-pending-reboot-elevated.ps1"
restartCommand = "shutdown.exe -f -r -t 0 -c \"packer restart\""
testRestartCommand = "shutdown.exe -f -r -t 60 -c \"packer restart test\""
abortTestRestartCommand = "shutdown.exe -a"
retryableDelay = 5 * time.Second
uploadTimeout = 5 * time.Minute
)
//go:embed windows-update.ps1
var windowsUpdatePs1 []byte
type Config struct {
common.PackerConfig `mapstructure:",squash"`
// The timeout for waiting for the machine to restart
RestartTimeout time.Duration `mapstructure:"restart_timeout"`
// Instructs the communicator to run the remote script as a
// Windows scheduled task, effectively elevating the remote
// user by impersonating a logged-in user.
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
// The updates search criteria.
// See the IUpdateSearcher::Search method at https://docs.microsoft.com/en-us/windows/desktop/api/wuapi/nf-wuapi-iupdatesearcher-search.
SearchCriteria string `mapstructure:"search_criteria"`
// Filters the installed Windows updates. If no filter is
// matched the update is NOT installed.
Filters []string `mapstructure:"filters"`
// Adds a limit to how many updates are installed at a time
UpdateLimit int `mapstructure:"update_limit"`
// Max times the provisioner will try install the updates
// in case of failure.
UpdateMaxRetries int `mapstructure:"update_max_retries"`
ctx interpolate.Context
}
type Provisioner struct {
config Config
}
func (b *Provisioner) ConfigSpec() hcldec.ObjectSpec {
return b.config.FlatMapstructure().HCL2Spec()
}
func (p *Provisioner) Prepare(raws ...interface{}) error {
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"execute_command",
},
},
}, raws...)
if err != nil {
return err
}
if p.config.RestartTimeout == 0 {
p.config.RestartTimeout = 4 * time.Hour
}
if p.config.Username == "" {
p.config.Username = "SYSTEM"
}
var errs error
if p.config.Username == "" {
errs = packer.MultiErrorAppend(errs,
errors.New("Must supply an 'username'"))
}
if p.config.UpdateLimit == 0 {
p.config.UpdateLimit = 1000
}
if p.config.UpdateMaxRetries == 0 {
p.config.UpdateMaxRetries = 5
}
return errs
}
func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, _ map[string]interface{}) error {
ui.Say("Uploading the Windows update elevated script...")
var buffer bytes.Buffer
err := elevatedTemplate.Execute(&buffer, elevatedOptions{
Username: p.config.Username,
Password: p.config.Password,
TaskDescription: "Packer Windows update elevated task",
TaskName: fmt.Sprintf("packer-windows-update-%s", uuid.TimeOrderedUUID()),
Command: p.windowsUpdateCommand(),
})
if err != nil {
fmt.Printf("Error creating elevated template: %s", err)
return err
}
err = retry.Config{StartTimeout: uploadTimeout}.Run(ctx, func(context.Context) error {
if err := comm.Upload(
elevatedPath,
bytes.NewReader(buffer.Bytes()),
nil); err != nil {
return fmt.Errorf("Error uploading the Windows update elevated script: %s", err)
}
return nil
})
if err != nil {
return err
}
ui.Say("Uploading the Windows update check for reboot required elevated script...")
buffer.Reset()
err = elevatedTemplate.Execute(&buffer, elevatedOptions{
Username: p.config.Username,
Password: p.config.Password,
TaskDescription: "Packer Windows update pending reboot elevated task",
TaskName: fmt.Sprintf("packer-windows-update-pending-reboot-%s", uuid.TimeOrderedUUID()),
Command: p.windowsUpdateCheckForRebootRequiredCommand(),
})
if err != nil {
fmt.Printf("Error creating elevated template: %s", err)
return err
}
err = retry.Config{StartTimeout: uploadTimeout}.Run(ctx, func(context.Context) error {
if err := comm.Upload(
pendingRebootElevatedPath,
bytes.NewReader(buffer.Bytes()),
nil); err != nil {
return fmt.Errorf("Error uploading the Windows update check for reboot required elevated script: %s", err)
}
return nil
})
if err != nil {
return err
}
ui.Say("Uploading the Windows update script...")
err = comm.Upload(
windowsUpdatePath,
bytes.NewReader(windowsUpdatePs1),
nil)
if err != nil {
return err
}
for {
restartPending, err := p.update(ctx, ui, comm)
if err != nil {
return err
}
if !restartPending {
return nil
}
err = p.restart(ctx, ui, comm)
if err != nil {
return err
}
}
}
func (p *Provisioner) update(ctx context.Context, ui packer.Ui, comm packer.Communicator) (bool, error) {
ui.Say("Running Windows update...")
var restartPending bool
err := retry.Config{
RetryDelay: func() time.Duration { return retryableDelay },
Tries: p.config.UpdateMaxRetries,
}.Run(ctx, func(ctx context.Context) error {
ui := NewUpdateUi(ui)
cmd := &packer.RemoteCmd{Command: elevatedCommand}
err := cmd.RunWithUi(ctx, comm, ui)
if err != nil {
return err
}
var exitStatus = cmd.ExitStatus()
if !ui.finished {
return fmt.Errorf("Windows update script did not finish")
}
switch exitStatus {
case 0:
return nil
case 101:
restartPending = true
return nil
case 2147942501: //windows 2012
restartPending = true
return nil
default:
return fmt.Errorf("Windows update script exited with non-zero exit status: %d", exitStatus)
}
})
return restartPending, err
}
func (p *Provisioner) restart(ctx context.Context, ui packer.Ui, comm packer.Communicator) error {
restartPending := true
for restartPending {
ui.Say("Restarting the machine...")
err := p.retryable(ctx, func(ctx context.Context) error {
cmd := &packer.RemoteCmd{Command: restartCommand}
err := cmd.RunWithUi(ctx, comm, ui)
if err != nil {
return err
}
exitStatus := cmd.ExitStatus()
if exitStatus != 0 {
return fmt.Errorf("Failed to restart the machine with exit status: %d", exitStatus)
}
return err
})
if err != nil {
return err
}
ui.Say("Waiting for machine to become available...")
err = p.retryable(ctx, func(ctx context.Context) error {
// wait for the machine to reboot.
cmd := &packer.RemoteCmd{Command: testRestartCommand}
err := cmd.RunWithUi(ctx, comm, ui)
if err != nil {
return err
}
exitStatus := cmd.ExitStatus()
if exitStatus != 0 {
return fmt.Errorf("Machine not yet available (exit status %d)", exitStatus)
}
cmd = &packer.RemoteCmd{Command: abortTestRestartCommand}
err = cmd.RunWithUi(ctx, comm, ui)
return err
})
if err != nil {
return err
}
ui.Say("Checking for pending restart...")
err = p.retryable(ctx, func(ctx context.Context) error {
ui := NewUpdateUi(ui)
cmd := &packer.RemoteCmd{Command: pendingRebootElevatedCommand}
err = cmd.RunWithUi(ctx, comm, ui)
if err != nil {
return err
}
if !ui.finished {
return fmt.Errorf("Windows update script did not finish")
}
exitStatus := cmd.ExitStatus()
switch exitStatus {
case 0:
restartPending = false
case 101:
restartPending = true
case 2147942501: //windows 2012
restartPending = true
default:
return fmt.Errorf("Machine not yet available (exit status %d)", exitStatus)
}
return err
})
if err != nil {
return err
}
if restartPending {
ui.Say("Restart is still pending...")
} else {
ui.Say("Restart complete")
}
}
return nil
}
// retryable will retry the given function over and over until a
// non-error is returned, RestartTimeout expires, or ctx is
// cancelled.
func (p *Provisioner) retryable(ctx context.Context, f func(ctx context.Context) error) error {
return retry.Config{
RetryDelay: func() time.Duration { return retryableDelay },
StartTimeout: p.config.RestartTimeout,
}.Run(ctx, f)
}
func (p *Provisioner) windowsUpdateCommand() string {
return fmt.Sprintf(
"PowerShell -ExecutionPolicy Bypass -OutputFormat Text -EncodedCommand %s",
base64.StdEncoding.EncodeToString(
encodeUtf16Le(fmt.Sprintf(
"%s%s%s -UpdateLimit %d",
windowsUpdatePath,
searchCriteriaArgument(p.config.SearchCriteria),
filtersArgument(p.config.Filters),
p.config.UpdateLimit))))
}
func (p *Provisioner) windowsUpdateCheckForRebootRequiredCommand() string {
return fmt.Sprintf(
"PowerShell -ExecutionPolicy Bypass -OutputFormat Text -EncodedCommand %s",
base64.StdEncoding.EncodeToString(
encodeUtf16Le(fmt.Sprintf(
"%s -OnlyCheckForRebootRequired",
windowsUpdatePath))))
}
func encodeUtf16Le(s string) []byte {
d := utf16.Encode([]rune(s))
b := make([]byte, len(d)*2)
for i, r := range d {
b[i*2] = byte(r)
b[i*2+1] = byte(r >> 8)
}
return b
}
func searchCriteriaArgument(searchCriteria string) string {
if searchCriteria == "" {
return ""
}
var buffer bytes.Buffer
buffer.WriteString(" -SearchCriteria ")
buffer.WriteString(escapePowerShellString(searchCriteria))
return buffer.String()
}
func filtersArgument(filters []string) string {
if filters == nil {
return ""
}
var buffer bytes.Buffer
buffer.WriteString(" -Filters ")
for i, filter := range filters {
if i > 0 {
buffer.WriteString(",")
}
buffer.WriteString(escapePowerShellString(filter))
}
return buffer.String()
}
func escapePowerShellString(value string) string {
return fmt.Sprintf(
"'%s'",
// escape single quotes with another single quote.
strings.ReplaceAll(value, "'", "''"))
}
================================================
FILE: update/provisioner.hcl2spec.go
================================================
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
package update
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatConfig is an auto-generated flat version of Config.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
RestartTimeout *string `mapstructure:"restart_timeout" cty:"restart_timeout" hcl:"restart_timeout"`
Username *string `mapstructure:"username" cty:"username" hcl:"username"`
Password *string `mapstructure:"password" cty:"password" hcl:"password"`
SearchCriteria *string `mapstructure:"search_criteria" cty:"search_criteria" hcl:"search_criteria"`
Filters []string `mapstructure:"filters" cty:"filters" hcl:"filters"`
UpdateLimit *int `mapstructure:"update_limit" cty:"update_limit" hcl:"update_limit"`
UpdateMaxRetries *int `mapstructure:"update_max_retries" cty:"update_max_retries" hcl:"update_max_retries"`
}
// FlatMapstructure returns a new FlatConfig.
// FlatConfig is an auto-generated flat version of Config.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatConfig)
}
// HCL2Spec returns the hcl spec of a Config.
// This spec is used by HCL to read the fields of Config.
// The decoded values from this spec will then be applied to a FlatConfig.
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
"restart_timeout": &hcldec.AttrSpec{Name: "restart_timeout", Type: cty.String, Required: false},
"username": &hcldec.AttrSpec{Name: "username", Type: cty.String, Required: false},
"password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false},
"search_criteria": &hcldec.AttrSpec{Name: "search_criteria", Type: cty.String, Required: false},
"filters": &hcldec.AttrSpec{Name: "filters", Type: cty.List(cty.String), Required: false},
"update_limit": &hcldec.AttrSpec{Name: "update_limit", Type: cty.Number, Required: false},
"update_max_retries": &hcldec.AttrSpec{Name: "update_max_retries", Type: cty.Number, Required: false},
}
return s
}
================================================
FILE: update/update_ui.go
================================================
package update
import (
"io"
"strings"
"github.com/hashicorp/packer-plugin-sdk/packer"
)
type UpdateUi struct {
ui packer.Ui
finished bool
}
func NewUpdateUi(ui packer.Ui) *UpdateUi {
return &UpdateUi{
ui: ui,
finished: false,
}
}
func (u *UpdateUi) Askf(s string, args ...any) (string, error) {
return u.ui.Askf(s, args...)
}
func (u *UpdateUi) Ask(s string) (string, error) {
return u.ui.Ask(s)
}
func (u *UpdateUi) Sayf(s string, args ...any) {
u.ui.Sayf(s, args...)
}
func (u *UpdateUi) Say(s string) {
if strings.HasPrefix(s, "Exiting with code ") {
u.finished = true
return
}
u.ui.Say(s)
}
func (u *UpdateUi) Message(s string) {
u.Say(s)
}
func (u *UpdateUi) Errorf(s string, args ...any) {
u.ui.Errorf(s, args...)
}
func (u *UpdateUi) Error(s string) {
u.ui.Error(s)
}
func (u *UpdateUi) Machine(t string, args ...string) {
u.ui.Machine(t, args...)
}
func (u *UpdateUi) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser) {
return u.ui.TrackProgress(src, currentSize, totalSize, stream)
}
================================================
FILE: update/windows-update.ps1
================================================
# see Using the Windows Update Agent API | Searching, Downloading, and Installing Updates
# at https://learn.microsoft.com/en-us/windows/win32/wua_sdk/searching--downloading--and-installing-updates
# see ISystemInformation interface
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isysteminformation
# see IUpdateSession interface
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatesession
# see IUpdateSearcher interface
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatesearcher
# see IUpdateSearcher::Search method
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-search
# see IUpdateDownloader interface
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatedownloader
# see IUpdateCollection interface
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatecollection
# see IUpdate interface
# at https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdate
# see xWindowsUpdateAgent DSC resource
# at https://github.com/dsccommunity/xWindowsUpdate/tree/master/source/DSCResources/MSFT_xWindowsUpdateAgent
# NB you can install common sets of updates with one of these settings:
# | Name | SearchCriteria | Filters |
# |---------------|-------------------------------------------|---------------|
# | Important | AutoSelectOnWebSites=1 and IsInstalled=0 | $true |
# | Recommended | BrowseOnly=0 and IsInstalled=0 | $true |
# | All | IsInstalled=0 | $true |
# | Optional Only | AutoSelectOnWebSites=0 and IsInstalled=0 | $_.BrowseOnly |
param(
[string]$SearchCriteria = 'BrowseOnly=0 and IsInstalled=0',
[string[]]$Filters = @('include:$true'),
[int]$UpdateLimit = 1000,
[switch]$OnlyCheckForRebootRequired = $false
)
$mock = $false
function ExitWithCode($exitCode) {
$host.SetShouldExit($exitCode)
Write-Output "Exiting with code $exitCode"
Exit
}
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'
trap {
Write-Output "ERROR: $_"
Write-Output (($_.ScriptStackTrace -split '\r?\n') -replace '^(.*)$','ERROR: $1')
Write-Output (($_.Exception.ToString() -split '\r?\n') -replace '^(.*)$','ERROR EXCEPTION: $1')
ExitWithCode 1
}
if ($mock) {
$mockWindowsUpdatePath = 'C:\Windows\Temp\windows-update-count-mock.txt'
if (!(Test-Path $mockWindowsUpdatePath)) {
Set-Content $mockWindowsUpdatePath 10
}
$count = [int]::Parse((Get-Content $mockWindowsUpdatePath).Trim())
if ($count) {
Write-Output "Synthetic reboot countdown counter is at $count"
Set-Content $mockWindowsUpdatePath (--$count)
ExitWithCode 101
}
Write-Output 'No Windows updates found'
ExitWithCode 0
}
Add-Type @'
using System;
using System.Runtime.InteropServices;
public static class Windows
{
[DllImport("kernel32", SetLastError=true)]
public static extern UInt64 GetTickCount64();
public static TimeSpan GetUptime()
{
return TimeSpan.FromMilliseconds(GetTickCount64());
}
}
'@
function Wait-Condition {
param(
[scriptblock]$Condition,
[int]$DebounceSeconds=15
)
process {
$begin = [Windows]::GetUptime()
do {
Start-Sleep -Seconds 1
try {
$result = &$Condition
} catch {
$result = $false
}
if (-not $result) {
$begin = [Windows]::GetUptime()
continue
}
} while ((([Windows]::GetUptime()) - $begin).TotalSeconds -lt $DebounceSeconds)
}
}
$operationResultCodes = @{
0 = "NotStarted";
1 = "InProgress";
2 = "Succeeded";
3 = "SucceededWithErrors";
4 = "Failed";
5 = "Aborted"
}
function LookupOperationResultCode($code) {
if ($operationResultCodes.ContainsKey($code)) {
return $operationResultCodes[$code]
}
return "Unknown Code $code"
}
function ExitWhenRebootRequired($rebootRequired = $false) {
# check for pending Windows Updates.
if (!$rebootRequired) {
$systemInformation = New-Object -ComObject 'Microsoft.Update.SystemInfo'
$rebootRequired = $systemInformation.RebootRequired
}
# check for pending Windows Features.
if (!$rebootRequired) {
$pendingPackagesKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending'
$pendingPackagesCount = (Get-ChildItem -ErrorAction SilentlyContinue $pendingPackagesKey | Measure-Object).Count
$rebootRequired = $pendingPackagesCount -gt 0
}
if ($rebootRequired) {
Write-Output 'Waiting for the Windows Modules Installer to exit...'
Wait-Condition {(Get-Process -ErrorAction SilentlyContinue TiWorker | Measure-Object).Count -eq 0}
ExitWithCode 101
}
}
# try to repair the windows update settings to work in non-preview mode.
# see https://github.com/rgl/packer-plugin-windows-update/issues/144
# see https://learn.microsoft.com/en-sg/answers/questions/1791668/powershell-command-outputting-system-comobject-on
function Repair-WindowsUpdate {
$settingsPath = 'C:\ProgramData\Microsoft\Windows\OneSettings\UusSettings.json'
if (!(Test-Path $settingsPath)) {
throw 'the windows update api is in an invalid state. see https://github.com/rgl/packer-plugin-windows-update/issues/144.'
}
$version = (New-Object -ComObject Microsoft.Update.AgentInfo).GetInfo('ProductVersionString')
$settings = Get-Content -Raw $settingsPath | ConvertFrom-Json
if ($settings.settings.EXCLUSIONS -notcontains $version) {
$settings.settings.EXCLUSIONS += $version
Write-Output 'Repairing the windows update settings to work in non-preview mode...'
Copy-Item $settingsPath "$settingsPath.backup.json" -Force
[System.IO.File]::WriteAllText(
$settingsPath,
($settings | ConvertTo-Json -Compress -Depth 100),
(New-Object System.Text.UTF8Encoding $false))
}
Write-Output 'Restarting the machine to retry a new windows update round...'
ExitWithCode 101
}
ExitWhenRebootRequired
if ($OnlyCheckForRebootRequired) {
Write-Output "$env:COMPUTERNAME restarted."
ExitWithCode 0
}
$updateFilters = $Filters | ForEach-Object {
$action, $expression = $_ -split ':',2
New-Object PSObject -Property @{
Action = $action
Expression = [ScriptBlock]::Create($expression)
}
}
function Test-IncludeUpdate($filters, $update) {
foreach ($filter in $filters) {
if (Where-Object -InputObject $update $filter.Expression) {
return $filter.Action -eq 'include'
}
}
return $false
}
$windowsOsVersion = [System.Environment]::OSVersion.Version
Write-Output 'Searching for Windows updates...'
$updatesToDownloadSize = 0
$updatesToDownload = New-Object -ComObject 'Microsoft.Update.UpdateColl'
$updatesToInstall = New-Object -ComObject 'Microsoft.Update.UpdateColl'
while ($true) {
try {
$updateSession = New-Object -ComObject 'Microsoft.Update.Session'
$updateSession.ClientApplicationID = 'packer-windows-update'
$updateSearcher = $updateSession.CreateUpdateSearcher()
$searchResult = $updateSearcher.Search($SearchCriteria)
if ($searchResult.ResultCode -eq 2) {
break
}
$searchStatus = LookupOperationResultCode($searchResult.ResultCode)
} catch {
$searchStatus = $_.ToString()
}
Write-Output "Search for Windows updates failed with '$searchStatus'. Retrying..."
Start-Sleep -Seconds 5
}
$rebootRequired = $false
for ($i = 0; $i -lt $searchResult.Updates.Count; ++$i) {
$update = $searchResult.Updates.Item($i)
# when the windows update api returns an invalid update object, repair
# windows update and signal a reboot to try again.
# see https://github.com/rgl/packer-plugin-windows-update/issues/144
# see The June 2024 preview update might impact applications using Windows Update APIs
# https://learn.microsoft.com/en-us/windows/release-health/status-windows-11-23h2#3351msgdesc
$expectedProperties = @(
'Title'
'MaxDownloadSize'
'LastDeploymentChangeTime'
'InstallationBehavior'
'AcceptEula'
)
$properties = $update `
| Get-Member $expectedProperties `
| Select-Object -ExpandProperty Name
if (!$properties -or (Compare-Object $expectedProperties $properties)) {
Repair-WindowsUpdate
}
$updateTitle = $update.Title
$updateMaxDownloadSize = $update.MaxDownloadSize
$updateDate = $update.LastDeploymentChangeTime.ToString('yyyy-MM-dd')
$updateSize = ($updateMaxDownloadSize/1024/1024).ToString('0.##')
$updateSummary = "Windows update ($updateDate; $updateSize MB): $updateTitle"
if (!(Test-IncludeUpdate $updateFilters $update)) {
Write-Output "Skipped (filter) $updateSummary"
continue
}
if ($update.InstallationBehavior.CanRequestUserInput) {
Write-Output "Warning The update '$updateTitle' has the CanRequestUserInput flag set (if the install hangs, you might need to exclude it with the filter 'exclude:`$_.InstallationBehavior.CanRequestUserInput' or 'exclude:`$_.Title -like '*$updateTitle*'')"
}
if (($updatesToInstall | Select-Object -ExpandProperty Title) -contains $updateTitle) {
Write-Output "Warning, Skipping queueing the duplicated titled update '$updateTitle'."
continue
}
Write-Output "Found $updateSummary"
$update.AcceptEula() | Out-Null
$updatesToDownloadSize += $updateMaxDownloadSize
$updatesToDownload.Add($update) | Out-Null
$updatesToInstall.Add($update) | Out-Null
if ($updatesToInstall.Count -ge $UpdateLimit) {
$rebootRequired = $true
break
}
}
if ($updatesToDownload.Count) {
$updateSize = ($updatesToDownloadSize/1024/1024).ToString('0.##')
Write-Output "Downloading Windows updates ($($updatesToDownload.Count) updates; $updateSize MB)..."
$updateDownloader = $updateSession.CreateUpdateDownloader()
# see https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa#remarks
if (($windowsOsVersion.Major -eq 6 -and $windowsOsVersion.Minor -gt 1) -or ($windowsOsVersion.Major -gt 6)) {
$updateDownloader.Priority = 4 # 1 (dpLow), 2 (dpNormal), 3 (dpHigh), 4 (dpExtraHigh).
} else {
# For versions lower then 6.2 highest prioirty is 3
$updateDownloader.Priority = 3 # 1 (dpLow), 2 (dpNormal), 3 (dpHigh).
}
$updateDownloader.Updates = $updatesToDownload
while ($true) {
$downloadResult = $updateDownloader.Download()
if ($downloadResult.ResultCode -eq 2) {
break
}
if ($downloadResult.ResultCode -eq 3) {
Write-Output "Download Windows updates succeeded with errors. Will retry after the next reboot."
$rebootRequired = $true
break
}
$downloadStatus = LookupOperationResultCode($downloadResult.ResultCode)
Write-Output "Download Windows updates failed with $downloadStatus. Retrying..."
Start-Sleep -Seconds 5
}
}
if ($updatesToInstall.Count) {
Write-Output 'Installing Windows updates...'
$updateInstaller = $updateSession.CreateUpdateInstaller()
$updateInstaller.Updates = $updatesToInstall
$installRebootRequired = $false
try {
$installResult = $updateInstaller.Install()
Write-Output "Windows update installation completed. Checking for more updates after a reboot..."
$installRebootRequired = $installResult.RebootRequired -or $true
} catch {
Write-Warning "Windows update installation failed with error:"
Write-Warning $_.Exception.ToString()
# Windows update install failed for some reason
# restart the machine and try again
$rebootRequired = $true
}
ExitWhenRebootRequired ($installRebootRequired -or $rebootRequired)
} else {
ExitWhenRebootRequired $rebootRequired
Write-Output 'No Windows updates found'
}
ExitWithCode 0
gitextract_5np1h6zz/
├── .devcontainer/
│ ├── Dockerfile
│ ├── devcontainer.json
│ ├── inputrc
│ ├── login.sh
│ └── setup.sh
├── .gitattributes
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .goreleaser.yml
├── .vscode/
│ └── settings.json
├── LICENSE.txt
├── Makefile
├── README.md
├── ci-release.sh
├── go.mod
├── go.sum
├── main.go
├── renovate.json5
├── renovate.sh
├── test.pkr.hcl
├── test.sh
└── update/
├── elevated-template.ps1
├── elevated.go
├── provisioner.go
├── provisioner.hcl2spec.go
├── update_ui.go
└── windows-update.ps1
SYMBOL INDEX (40 symbols across 5 files)
FILE: main.go
function main (line 17) | func main() {
FILE: update/elevated.go
type elevatedOptions (line 10) | type elevatedOptions struct
FILE: update/provisioner.go
constant elevatedPath (line 28) | elevatedPath = "C:/Windows/Temp/packer-windows-update-el...
constant elevatedCommand (line 29) | elevatedCommand = "PowerShell -ExecutionPolicy Bypass -Outp...
constant windowsUpdatePath (line 30) | windowsUpdatePath = "C:/Windows/Temp/packer-windows-update.ps1"
constant pendingRebootElevatedPath (line 31) | pendingRebootElevatedPath = "C:/Windows/Temp/packer-windows-update-pe...
constant pendingRebootElevatedCommand (line 32) | pendingRebootElevatedCommand = "PowerShell -ExecutionPolicy Bypass -Outp...
constant restartCommand (line 33) | restartCommand = "shutdown.exe -f -r -t 0 -c \"packer rest...
constant testRestartCommand (line 34) | testRestartCommand = "shutdown.exe -f -r -t 60 -c \"packer res...
constant abortTestRestartCommand (line 35) | abortTestRestartCommand = "shutdown.exe -a"
constant retryableDelay (line 36) | retryableDelay = 5 * time.Second
constant uploadTimeout (line 37) | uploadTimeout = 5 * time.Minute
type Config (line 43) | type Config struct
type Provisioner (line 73) | type Provisioner struct
method ConfigSpec (line 77) | func (b *Provisioner) ConfigSpec() hcldec.ObjectSpec {
method Prepare (line 81) | func (p *Provisioner) Prepare(raws ...interface{}) error {
method Provision (line 121) | func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, com...
method update (line 200) | func (p *Provisioner) update(ctx context.Context, ui packer.Ui, comm p...
method restart (line 233) | func (p *Provisioner) restart(ctx context.Context, ui packer.Ui, comm ...
method retryable (line 317) | func (p *Provisioner) retryable(ctx context.Context, f func(ctx contex...
method windowsUpdateCommand (line 324) | func (p *Provisioner) windowsUpdateCommand() string {
method windowsUpdateCheckForRebootRequiredCommand (line 336) | func (p *Provisioner) windowsUpdateCheckForRebootRequiredCommand() str...
function encodeUtf16Le (line 345) | func encodeUtf16Le(s string) []byte {
function searchCriteriaArgument (line 355) | func searchCriteriaArgument(searchCriteria string) string {
function filtersArgument (line 368) | func filtersArgument(filters []string) string {
function escapePowerShellString (line 387) | func escapePowerShellString(value string) string {
FILE: update/provisioner.hcl2spec.go
type FlatConfig (line 12) | type FlatConfig struct
method HCL2Spec (line 40) | func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
method FlatMapstructure (line 33) | func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hclde...
FILE: update/update_ui.go
type UpdateUi (line 10) | type UpdateUi struct
method Askf (line 22) | func (u *UpdateUi) Askf(s string, args ...any) (string, error) {
method Ask (line 26) | func (u *UpdateUi) Ask(s string) (string, error) {
method Sayf (line 30) | func (u *UpdateUi) Sayf(s string, args ...any) {
method Say (line 34) | func (u *UpdateUi) Say(s string) {
method Message (line 42) | func (u *UpdateUi) Message(s string) {
method Errorf (line 46) | func (u *UpdateUi) Errorf(s string, args ...any) {
method Error (line 50) | func (u *UpdateUi) Error(s string) {
method Machine (line 54) | func (u *UpdateUi) Machine(t string, args ...string) {
method TrackProgress (line 58) | func (u *UpdateUi) TrackProgress(src string, currentSize, totalSize in...
function NewUpdateUi (line 15) | func NewUpdateUi(ui packer.Ui) *UpdateUi {
Condensed preview — 27 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (117K chars).
[
{
"path": ".devcontainer/Dockerfile",
"chars": 1107,
"preview": "# syntax=docker.io/docker/dockerfile:1.23\n\n# see https://github.com/devcontainers/images/blob/main/src/base-debian/manif"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 822,
"preview": "{\n \"name\": \"Packer\",\n \"dockerFile\": \"Dockerfile\",\n \"context\": \"..\",\n \"runArgs\": [\n \"--group-add=108\", // 108 is t"
},
{
"path": ".devcontainer/inputrc",
"chars": 203,
"preview": "set input-meta on\nset output-meta on\nset show-all-if-ambiguous on\nset completion-ignore-case on\n\n\"\\e[A\": history-search-"
},
{
"path": ".devcontainer/login.sh",
"chars": 118,
"preview": "export EDITOR=code\nexport PAGER=less\n\nalias l='ls -lF --color'\nalias ll='l -a'\nalias h='history 25'\nalias j='jobs -l'\n"
},
{
"path": ".devcontainer/setup.sh",
"chars": 109,
"preview": "#!/bin/bash\nset -euxo pipefail\n\npushd /home/vscode\nsudo chown vscode:vscode .ssh && sudo chmod 700 .ssh\npopd\n"
},
{
"path": ".gitattributes",
"chars": 20,
"preview": "/update/*.ps1 -text\n"
},
{
"path": ".github/workflows/build.yml",
"chars": 1056,
"preview": "name: Build\non: [push, pull_request]\njobs:\n build:\n name: Build\n runs-on: windows-2022\n steps:\n - name: C"
},
{
"path": ".gitignore",
"chars": 96,
"preview": "dist/\npacker-plugin-windows-update\npacker-plugin-windows-update.exe\ntmp*\n.idea/\noutput-*/\n*.log\n"
},
{
"path": ".goreleaser.yml",
"chars": 1097,
"preview": "version: 2\nbuilds:\n - env:\n - CGO_ENABLED=0\n goos:\n - linux\n - darwin\n - windows\n goarch:\n "
},
{
"path": ".vscode/settings.json",
"chars": 55,
"preview": "{\n \"cSpell.words\": [\n \"devcontainers\"\n ]\n}"
},
{
"path": "LICENSE.txt",
"chars": 16725,
"preview": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\""
},
{
"path": "Makefile",
"chars": 1806,
"preview": "GOPATH := $(shell go env GOPATH | tr '\\\\' '/')\nGOEXE := $(shell go env GOEXE)\nGOHOSTOS := $(shell go env GOHOSTOS)\nGOHOS"
},
{
"path": "README.md",
"chars": 4442,
"preview": "# Packer Windows Update Provisioner\n\n[\"\nGOHOSTARCH=\"$(go env GOHOSTARCH)\"\nPLUGIN_PATH=\"$(\n j"
},
{
"path": "update/elevated-template.ps1",
"chars": 3875,
"preview": "Set-StrictMode -Version Latest\r\n$ErrorActionPreference = 'Stop'\r\n$ProgressPreference = 'SilentlyContinue'\r\ntrap {\r\n W"
},
{
"path": "update/elevated.go",
"chars": 567,
"preview": "// NB this code was based on https://github.com/hashicorp/packer/blob/370b67497e90785b71be1b6fcc6430de487d644e/provision"
},
{
"path": "update/provisioner.go",
"chars": 10910,
"preview": "//go:generate packer-sdc mapstructure-to-hcl2 -type Config\n\n// NB this code was based on https://github.com/hashicorp/pa"
},
{
"path": "update/provisioner.hcl2spec.go",
"chars": 4325,
"preview": "// Code generated by \"packer-sdc mapstructure-to-hcl2\"; DO NOT EDIT.\n\npackage update\n\nimport (\n\t\"github.com/hashicorp/hc"
},
{
"path": "update/update_ui.go",
"chars": 1094,
"preview": "package update\n\nimport (\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/hashicorp/packer-plugin-sdk/packer\"\n)\n\ntype UpdateUi struct {\n\tu"
},
{
"path": "update/windows-update.ps1",
"chars": 12722,
"preview": "# see Using the Windows Update Agent API | Searching, Downloading, and Installing Updates\r\n# at https://learn.micros"
}
]
About this extraction
This page contains the full source code of the rgl/packer-provisioner-windows-update GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 27 files (108.9 KB), approximately 38.2k tokens, and a symbol index with 40 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.