Merge pull request #2 from hashicorp/master
merge from hashicorp/packer
This commit is contained in:
commit
807f39284d
|
@ -5,4 +5,6 @@
|
|||
*.md text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.hcl text eol=lf
|
||||
go.mod text eol=lf
|
||||
go.sum text eol=lf
|
||||
common/test-fixtures/root/* eol=lf
|
||||
|
|
|
@ -259,6 +259,28 @@ localized code generation. Say you are working on the Amazon builder: running
|
|||
`go generate ./builder/amazon/...` will do that for you. Make sure that the
|
||||
latest code generation tool is installed by running `make install-gen-deps`.
|
||||
|
||||
#### Code linting
|
||||
|
||||
Packer relies on [golangci-lint](https://github.com/golangci/golangci-lint) for linting its Go code base, excluding any generated code created by `go generate`. Linting is executed on new files during Travis builds via `make ci`; the linting of existing code base is only executed when running `make lint`. Linting a large project like Packer is an iterative process so existing code base will have issues that are actively being fixed; pull-requests that fix existing linting issues are always welcomed :smile:.
|
||||
|
||||
The main configuration for golangci-lint is the `.golangci.yml` in the project root. See `golangci-lint --help` for a list of flags that can be used to override the default configuration.
|
||||
|
||||
Run golangci-lint on the entire Packer code base.
|
||||
```
|
||||
make lint
|
||||
```
|
||||
|
||||
Run golangci-lint on a single pkg or directory; PKG_NAME expands to /builder/amazon/...
|
||||
```
|
||||
make lint PKG_NAME=builder/amazon
|
||||
```
|
||||
|
||||
Note: linting on Travis uses the `--new-from-rev=origin/master` flag to only lint new files added within a branch or pull-request. To run this check locally you can use the `ci-lint` make target. See [golangci-lint in CI](https://github.com/golangci/golangci-lint#faq) for more information.
|
||||
|
||||
```
|
||||
make ci-lint
|
||||
```
|
||||
|
||||
#### Running Unit Tests
|
||||
|
||||
You can run tests for individual packages using commands like this:
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
issues:
|
||||
# List of regexps of issue texts to exclude, empty list by default.
|
||||
# But independently from this option we use default exclude patterns,
|
||||
# it can be disabled by `exclude-use-default: false`. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`
|
||||
|
||||
exclude-rules:
|
||||
# Exclude gosimple bool check
|
||||
- linters:
|
||||
- gosimple
|
||||
text: "S(1002|1008|1021)"
|
||||
# Exclude failing staticchecks for now
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA(1006|1019|4006|4010|4017|5007|6005|9004):"
|
||||
# Exclude lll issues for long lines with go:generate
|
||||
- linters:
|
||||
- lll
|
||||
source: "^//go:generate "
|
||||
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
max-issues-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- deadcode
|
||||
- errcheck
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unused
|
||||
- varcheck
|
||||
fast: true
|
||||
|
||||
# options for analysis running
|
||||
run:
|
||||
# default concurrency is a available CPU number
|
||||
concurrency: 4
|
||||
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 10m
|
||||
|
||||
# exit code when at least one issue was found, default is 1
|
||||
issues-exit-code: 1
|
||||
|
||||
# include test files or not, default is true
|
||||
tests: true
|
||||
|
||||
# list of build tags, all linters use it. Default is empty list.
|
||||
#build-tags:
|
||||
# - mytag
|
||||
|
||||
# which dirs to skip: issues from them won't be reported;
|
||||
# can use regexp here: generated.*, regexp is applied on full path;
|
||||
# default value is empty list, but default dirs are skipped independently
|
||||
# from this option's value (see skip-dirs-use-default).
|
||||
#skip-dirs:
|
||||
# - src/external_libs
|
||||
# - autogenerated_by_my_lib
|
||||
|
||||
# default is true. Enables skipping of directories:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs-use-default: true
|
||||
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
# no need to include all autogenerated files, we confidently recognize
|
||||
# autogenerated files. If it's not please let us know.
|
||||
skip-files:
|
||||
- ".*\\.hcl2spec\\.go$"
|
||||
# - lib/bad.go
|
||||
|
||||
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
modules-download-mode: vendor
|
||||
|
||||
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
|
||||
# make issues output unique by line, default is true
|
||||
uniq-by-line: true
|
||||
|
||||
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
ignore: fmt:.*,io/ioutil:^Read.*,io:Close
|
||||
|
||||
# path to a file containing a list of functions to exclude from checking
|
||||
# see https://github.com/kisielk/errcheck#excluding-functions for details
|
||||
#exclude: /path/to/file.txt
|
21
.travis.yml
21
.travis.yml
|
@ -4,20 +4,21 @@ env:
|
|||
os:
|
||||
- osx
|
||||
|
||||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.12.x
|
||||
|
||||
script:
|
||||
- df -h
|
||||
- travis_wait make ci
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
matrix:
|
||||
jobs:
|
||||
fast_finish: true
|
||||
include:
|
||||
- go: "1.13.x"
|
||||
name: "go test"
|
||||
script:
|
||||
- df -h
|
||||
- travis_wait make ci
|
||||
- go: "1.13.x"
|
||||
name: "go lint"
|
||||
script: travis_wait make ci-lint
|
||||
|
||||
|
|
45
CHANGELOG.md
45
CHANGELOG.md
|
@ -1,19 +1,56 @@
|
|||
## 1.5.2 (Upcoming)
|
||||
** New Builder ** The vsphere-iso builder, previously maintained by JetBrains,
|
||||
## 1.5.4 (February 14, 2020)
|
||||
no-change release to fix code-signing on OSX binaries. Since checksums for these
|
||||
binaries has changed, we are releasing a second time to prevent confusion.
|
||||
|
||||
## 1.5.3 (February 14, 2020)
|
||||
|
||||
### IMPROVEMENTS:
|
||||
* builder/vsphere: Add ability to define multiple NICs for vsphere-iso
|
||||
[GH-8739]
|
||||
* builder/vsphere: Add option to remove CD-ROM drives. [GH-8690]
|
||||
* core: Add validation to catch when users accidentally add duplicate fields to
|
||||
template [GH-8725]
|
||||
|
||||
### Bug Fixes:
|
||||
* core/hcl2: Fix template prepare/validation for HCL2 templates [GH-8742]
|
||||
* core: Fix `build` template function interpolation [GH-8727]
|
||||
|
||||
## 1.5.2 (February 12, 2020)
|
||||
**New Builder** The vsphere-iso builder, previously maintained by JetBrains,
|
||||
has been merged with the Packer core. It will be officially supported by the
|
||||
Packer team at HashiCorp moving forward. [GH-8480]
|
||||
|
||||
**HCL2 variables & functions** HCL2 configurations can now use `variable`,
|
||||
`variables`, `locals`, and functions [GH-8588].
|
||||
|
||||
### IMPROVEMENTS:
|
||||
* builder/alicloud: Add AlicloudProfile option. [GH-8560]
|
||||
* builder/amazon: Add max_retries option to aws builders [GH-8709]
|
||||
* builder/amazon: Add source AMI owner ID/name to template engines [GH-8550]
|
||||
* builder/amazon: Update instance waiters to use global waiter settings set by
|
||||
`AWS_POLL_DELAY_SECONDS` and `AWS_TIMEOUT_SECONDS` [GH-8699]
|
||||
* builder/azure: Allow users to use custom key vault for storing Windows
|
||||
certificates [GH-8704]
|
||||
* builder/azure: Set expiry for image versions in SIG [GH-8561]
|
||||
* builder/proxmox: Add option to upload the boot ISO rather than pointing out a
|
||||
previously manually uploaded one. [GH-8624]
|
||||
* builder/vagrant: Fix a crash in the Vagrant driver [GH-8607]
|
||||
* builder/yandex: Add service account ID to config [GH-8717]
|
||||
* communicator/winrm: Users can now override winrm_host with a static IP even
|
||||
when using cloud builders. [GH-8675]
|
||||
* core/hcl2: Fix bug preventing reading slices within other slices [GH-8669]
|
||||
* core: Interpolation within post-processors can now access build-specific
|
||||
values like Host IP, communicator password, and more [GH-8632]
|
||||
* core: Add `PACKER_PLUGIN_PATH` to list of supported paths for plugin
|
||||
discovery [GH-8616]
|
||||
* core: clean up messy log line in plugin execution. [GH-8542]
|
||||
* core: Ensure `PACKER_HTTP_ADDR` is always set for any builder that provides a
|
||||
HTTP server for file transfer [GH-8654]
|
||||
* core: Fix loading external plugins defined in PACKER_CONFIG [GH-8582]
|
||||
* core: Log name of postprocessor running to disambiguate long chains of post-
|
||||
processors. [GH-8613]
|
||||
* core: Packer can use isos in-place on Windows again, instead of copying them
|
||||
into its cache. [GH-7627]
|
||||
* core: step_download: return without error if Urls is empty [GH-8579]
|
||||
* post-processor/vsphere-template] Simplify method to use vm.MarkAsTemplate
|
||||
(optionally) [GH-8511]
|
||||
|
@ -26,6 +63,9 @@ Packer team at HashiCorp moving forward. [GH-8480]
|
|||
* builder/amazon: Allow AWS builder pre-validation to pass when subnet filters
|
||||
are present [GH-8622]
|
||||
* builder/azure: Fix bug where deployments were not being cleaned up: [GH-8496]
|
||||
* builder/azure: Fix issue where WinRMPassword was being left unset [GH-8670]
|
||||
* builder/lxd: Fix file uploading issue when using the file provisioner
|
||||
[GH-8636]
|
||||
* builder/null: Fix crash when configuring builder using HCL2. [GH-8612]
|
||||
* builder/osc: Fix ssh host detection in Public Cloud and Nets [GH-8414]
|
||||
* builder/vagrant: Fix bug with reading key from a path with spaces [GH-8605]
|
||||
|
@ -33,6 +73,7 @@ Packer team at HashiCorp moving forward. [GH-8480]
|
|||
* builder/virtualbox-vm: use config as a non pointer to avoid a panic [GH-8576]
|
||||
* core: Fix crash when build.sources is set to an invalid name [GH-8569]
|
||||
* core: Fix error loading .packerconfig [GH-8623]
|
||||
* core: Fix loading local ISO files when using `iso_target_path` [GH-8689]
|
||||
* core: Fix loading of external plugins. GH-8543]
|
||||
* post-processor/docker-tag: Fix regression if no tags were specified.
|
||||
[GH-8593]
|
||||
|
|
23
Makefile
23
Makefile
|
@ -18,7 +18,8 @@ GOLDFLAGS=-X $(GIT_IMPORT).GitCommit=$(GIT_COMMIT)$(GIT_DIRTY)
|
|||
|
||||
export GOLDFLAGS
|
||||
|
||||
.PHONY: bin checkversion ci default install-build-deps install-gen-deps fmt fmt-docs fmt-examples generate releasebin test testacc testrace
|
||||
.PHONY: bin checkversion ci ci-lint default install-build-deps install-gen-deps fmt fmt-docs fmt-examples generate install-lint-deps lint \
|
||||
releasebin test testacc testrace
|
||||
|
||||
default: install-build-deps install-gen-deps generate testrace dev releasebin package dev fmt fmt-check mode-check fmt-docs fmt-examples
|
||||
|
||||
|
@ -49,12 +50,16 @@ install-gen-deps: ## Install dependencies for code generation
|
|||
# dir. `go get` will change our deps and the following deps are not part of
|
||||
# out code dependencies; so a go mod tidy will remove them again. `go
|
||||
# install` seems to install the last tagged version and we want to install
|
||||
# master.
|
||||
# master.
|
||||
@(cd $(TEMPDIR) && GO111MODULE=on go get github.com/mna/pigeon@master)
|
||||
@(cd $(TEMPDIR) && GO111MODULE=on go get github.com/alvaroloes/enumer@master)
|
||||
@go install ./cmd/struct-markdown
|
||||
@go install ./cmd/mapstructure-to-hcl2
|
||||
|
||||
install-lint-deps: ## Install linter dependencies
|
||||
@echo "==> Updating linter dependencies..."
|
||||
@curl -sSfL -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.23.1
|
||||
|
||||
dev: ## Build and install a development build
|
||||
@grep 'const VersionPrerelease = ""' version/version.go > /dev/null ; if [ $$? -eq 0 ]; then \
|
||||
echo "ERROR: You must add prerelease tags to version/version.go prior to making a dev build."; \
|
||||
|
@ -66,6 +71,20 @@ dev: ## Build and install a development build
|
|||
@cp $(GOPATH)/bin/packer bin/packer
|
||||
@cp $(GOPATH)/bin/packer pkg/$(GOOS)_$(GOARCH)
|
||||
|
||||
lint: install-lint-deps ## Lint Go code
|
||||
@if [ ! -z $(PKG_NAME) ]; then \
|
||||
echo "golangci-lint run ./$(PKG_NAME)/..."; \
|
||||
golangci-lint run ./$(PKG_NAME)/...; \
|
||||
else \
|
||||
echo "golangci-lint run"; \
|
||||
golangci-lint run; \
|
||||
fi
|
||||
|
||||
ci-lint: install-lint-deps ## On ci only lint newly added Go source files
|
||||
@echo "==> Running linter on newly added Go source files..."
|
||||
GO111MODULE=on golangci-lint run --new-from-rev=origin/master
|
||||
|
||||
|
||||
fmt: ## Format Go code
|
||||
@go fmt ./...
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ package chroot
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"runtime"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/common/chroot"
|
||||
|
|
|
@ -41,6 +41,7 @@ type FlatConfig struct {
|
|||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MaxRetries *int `mapstructure:"max_retries" required:"false" cty:"max_retries"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
|
@ -112,6 +113,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
|
|
|
@ -4,13 +4,13 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -3,10 +3,10 @@ package chroot
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
|
|
@ -60,6 +60,10 @@ type AccessConfig struct {
|
|||
// This allows skipping TLS
|
||||
// verification of the AWS EC2 endpoint. The default is false.
|
||||
InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify" required:"false"`
|
||||
// This is the maximum number of times an API call is retried, in the case
|
||||
// where requests are being throttled or experiencing transient failures.
|
||||
// The delay between the subsequent API calls increases exponentially.
|
||||
MaxRetries int `mapstructure:"max_retries" required:"false"`
|
||||
// The MFA
|
||||
// [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm)
|
||||
// code. This should probably be a user variable since it changes all the
|
||||
|
@ -134,6 +138,9 @@ func (c *AccessConfig) Session() (*session.Session, error) {
|
|||
}
|
||||
|
||||
config := aws.NewConfig().WithCredentialsChainVerboseErrors(true)
|
||||
if c.MaxRetries > 0 {
|
||||
config = config.WithMaxRetries(c.MaxRetries)
|
||||
}
|
||||
|
||||
staticCreds := credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token)
|
||||
if _, err := staticCreds.Get(); err != credentials.ErrStaticCredentialsEmpty {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
|
|
|
@ -11,6 +11,7 @@ package ebs
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
|
|
|
@ -21,6 +21,7 @@ type FlatConfig struct {
|
|||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MaxRetries *int `mapstructure:"max_retries" required:"false" cty:"max_retries"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
|
@ -147,6 +148,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
|
|
|
@ -64,6 +64,7 @@ type FlatConfig struct {
|
|||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MaxRetries *int `mapstructure:"max_retries" required:"false" cty:"max_retries"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
|
@ -191,6 +192,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package ebssurrogate
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/builder/amazon/common"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/builder/amazon/common"
|
||||
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ type FlatConfig struct {
|
|||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MaxRetries *int `mapstructure:"max_retries" required:"false" cty:"max_retries"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
|
@ -171,6 +172,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
|
|
|
@ -9,13 +9,13 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/builder"
|
||||
awscommon "github.com/hashicorp/packer/builder/amazon/common"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
|
|
|
@ -21,6 +21,7 @@ type FlatConfig struct {
|
|||
CustomEndpointEc2 *string `mapstructure:"custom_endpoint_ec2" required:"false" cty:"custom_endpoint_ec2"`
|
||||
DecodeAuthZMessages *bool `mapstructure:"decode_authorization_messages" required:"false" cty:"decode_authorization_messages"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify"`
|
||||
MaxRetries *int `mapstructure:"max_retries" required:"false" cty:"max_retries"`
|
||||
MFACode *string `mapstructure:"mfa_code" required:"false" cty:"mfa_code"`
|
||||
ProfileName *string `mapstructure:"profile" required:"false" cty:"profile"`
|
||||
RawRegion *string `mapstructure:"region" required:"true" cty:"region"`
|
||||
|
@ -154,6 +155,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"custom_endpoint_ec2": &hcldec.AttrSpec{Name: "custom_endpoint_ec2", Type: cty.String, Required: false},
|
||||
"decode_authorization_messages": &hcldec.AttrSpec{Name: "decode_authorization_messages", Type: cty.Bool, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"max_retries": &hcldec.AttrSpec{Name: "max_retries", Type: cty.Number, Required: false},
|
||||
"mfa_code": &hcldec.AttrSpec{Name: "mfa_code", Type: cty.String, Required: false},
|
||||
"profile": &hcldec.AttrSpec{Name: "profile", Type: cty.String, Required: false},
|
||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||
|
|
|
@ -231,8 +231,16 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
keyVaultDeploymentName := b.stateBag.Get(constants.ArmKeyVaultDeploymentName).(string)
|
||||
steps = []multistep.Step{
|
||||
NewStepCreateResourceGroup(azureClient, ui),
|
||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetKeyVaultDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, &b.config, keyVaultDeploymentName, GetKeyVaultDeployment),
|
||||
}
|
||||
if b.config.BuildKeyVaultName == "" {
|
||||
steps = append(steps,
|
||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetKeyVaultDeployment),
|
||||
NewStepDeployTemplate(azureClient, ui, &b.config, keyVaultDeploymentName, GetKeyVaultDeployment),
|
||||
)
|
||||
} else {
|
||||
steps = append(steps, NewStepCertificateInKeyVault(&azureClient.VaultClient, ui, &b.config))
|
||||
}
|
||||
steps = append(steps,
|
||||
NewStepGetCertificate(azureClient, ui),
|
||||
NewStepSetCertificate(&b.config, ui),
|
||||
NewStepValidateTemplate(azureClient, ui, &b.config, GetVirtualMachineDeployment),
|
||||
|
@ -261,7 +269,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
NewStepDeleteResourceGroup(azureClient, ui),
|
||||
NewStepDeleteOSDisk(azureClient, ui),
|
||||
NewStepDeleteAdditionalDisks(azureClient, ui),
|
||||
}
|
||||
)
|
||||
} else {
|
||||
return nil, fmt.Errorf("Builder does not support the os_type '%s'", b.config.OSType)
|
||||
}
|
||||
|
@ -396,6 +404,13 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) {
|
|||
}
|
||||
|
||||
stateBag.Put(constants.ArmKeyVaultName, b.config.tmpKeyVaultName)
|
||||
stateBag.Put(constants.ArmIsExistingKeyVault, false)
|
||||
if b.config.BuildKeyVaultName != "" {
|
||||
stateBag.Put(constants.ArmKeyVaultName, b.config.BuildKeyVaultName)
|
||||
b.config.tmpKeyVaultName = b.config.BuildKeyVaultName
|
||||
stateBag.Put(constants.ArmIsExistingKeyVault, true)
|
||||
}
|
||||
|
||||
stateBag.Put(constants.ArmNicName, b.config.tmpNicName)
|
||||
stateBag.Put(constants.ArmPublicIPAddressName, b.config.tmpPublicIPAddressName)
|
||||
stateBag.Put(constants.ArmResourceGroupName, b.config.BuildResourceGroupName)
|
||||
|
|
|
@ -147,20 +147,20 @@ type Config struct {
|
|||
// If set to true, Virtual Machines deployed from the latest version of the
|
||||
// Image Definition won't use this Image Version.
|
||||
SharedGalleryImageVersionExcludeFromLatest bool `mapstructure:"shared_gallery_image_version_exclude_from_latest" required:"false"`
|
||||
// PublisherName for your base image. See
|
||||
// Name of the publisher to use for your base image (Azure Marketplace Images only). See
|
||||
// [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/)
|
||||
// for details.
|
||||
//
|
||||
// CLI example `az vm image list-publishers --location westus`
|
||||
ImagePublisher string `mapstructure:"image_publisher" required:"true"`
|
||||
// Offer for your base image. See
|
||||
// Name of the publisher's offer to use for your base image (Azure Marketplace Images only). See
|
||||
// [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/)
|
||||
// for details.
|
||||
//
|
||||
// CLI example
|
||||
// `az vm image list-offers --location westus --publisher Canonical`
|
||||
ImageOffer string `mapstructure:"image_offer" required:"true"`
|
||||
// SKU for your base image. See
|
||||
// SKU of the image offer to use for your base image (Azure Marketplace Images only). See
|
||||
// [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/)
|
||||
// for details.
|
||||
//
|
||||
|
@ -176,24 +176,24 @@ type Config struct {
|
|||
// CLI example
|
||||
// `az vm image list --location westus --publisher Canonical --offer UbuntuServer --sku 16.04.0-LTS --all`
|
||||
ImageVersion string `mapstructure:"image_version" required:"false"`
|
||||
// Specify a custom VHD to use. If this value is set, do
|
||||
// URL to a custom VHD to use for your base image. If this value is set, do
|
||||
// not set image_publisher, image_offer, image_sku, or image_version.
|
||||
ImageUrl string `mapstructure:"image_url" required:"true"`
|
||||
// Name of a custom managed image to use for your base image. If this value is set, do
|
||||
// not set image_publisher, image_offer, image_sku, or image_version.
|
||||
ImageUrl string `mapstructure:"image_url" required:"false"`
|
||||
// Specify the source managed image's resource group used to use. If this
|
||||
// value is set, do not set image\_publisher, image\_offer, image\_sku, or
|
||||
// image\_version. If this value is set, the value
|
||||
// `custom_managed_image_name` must also be set. See
|
||||
// [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images)
|
||||
// to learn more about managed images.
|
||||
CustomManagedImageResourceGroupName string `mapstructure:"custom_managed_image_resource_group_name" required:"false"`
|
||||
// Specify the source managed image's name to use. If this value is set, do
|
||||
// not set image\_publisher, image\_offer, image\_sku, or image\_version.
|
||||
// If this value is set, the value
|
||||
// `custom_managed_image_resource_group_name` must also be set. See
|
||||
// [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images)
|
||||
// to learn more about managed images.
|
||||
CustomManagedImageName string `mapstructure:"custom_managed_image_name" required:"false"`
|
||||
customManagedImageID string
|
||||
CustomManagedImageName string `mapstructure:"custom_managed_image_name" required:"true"`
|
||||
|
||||
// Name of a custom managed image's resource group to use for your base image. If this
|
||||
// value is set, image_publisher, image_offer, image_sku, or image_version.
|
||||
// `custom_managed_image_name` must also be set. See
|
||||
// [documentation](https://docs.microsoft.com/en-us/azure/storage/storage-managed-disks-overview#images)
|
||||
// to learn more about managed images.
|
||||
CustomManagedImageResourceGroupName string `mapstructure:"custom_managed_image_resource_group_name" required:"true"`
|
||||
customManagedImageID string
|
||||
|
||||
Location string `mapstructure:"location"`
|
||||
// Size of the VM used for building. This can be changed when you deploy a
|
||||
|
@ -253,7 +253,10 @@ type Config struct {
|
|||
// group is deleted at the end of the build.
|
||||
TempResourceGroupName string `mapstructure:"temp_resource_group_name"`
|
||||
// Specify an existing resource group to run the build in.
|
||||
BuildResourceGroupName string `mapstructure:"build_resource_group_name"`
|
||||
BuildResourceGroupName string `mapstructure:"build_resource_group_name"`
|
||||
// Specify an existing key vault to use for uploading certificates to the
|
||||
// instance to connect.
|
||||
BuildKeyVaultName string `mapstructure:"build_key_vault_name"`
|
||||
storageAccountBlobEndpoint string
|
||||
// This value allows you to
|
||||
// set a virtual_network_name and obtain a public IP. If this value is not
|
||||
|
|
|
@ -36,9 +36,9 @@ type FlatConfig struct {
|
|||
ImageOffer *string `mapstructure:"image_offer" required:"true" cty:"image_offer"`
|
||||
ImageSku *string `mapstructure:"image_sku" required:"true" cty:"image_sku"`
|
||||
ImageVersion *string `mapstructure:"image_version" required:"false" cty:"image_version"`
|
||||
ImageUrl *string `mapstructure:"image_url" required:"false" cty:"image_url"`
|
||||
CustomManagedImageResourceGroupName *string `mapstructure:"custom_managed_image_resource_group_name" required:"false" cty:"custom_managed_image_resource_group_name"`
|
||||
CustomManagedImageName *string `mapstructure:"custom_managed_image_name" required:"false" cty:"custom_managed_image_name"`
|
||||
ImageUrl *string `mapstructure:"image_url" required:"true" cty:"image_url"`
|
||||
CustomManagedImageName *string `mapstructure:"custom_managed_image_name" required:"true" cty:"custom_managed_image_name"`
|
||||
CustomManagedImageResourceGroupName *string `mapstructure:"custom_managed_image_resource_group_name" required:"true" cty:"custom_managed_image_resource_group_name"`
|
||||
Location *string `mapstructure:"location" cty:"location"`
|
||||
VMSize *string `mapstructure:"vm_size" required:"false" cty:"vm_size"`
|
||||
ManagedImageResourceGroupName *string `mapstructure:"managed_image_resource_group_name" cty:"managed_image_resource_group_name"`
|
||||
|
@ -53,6 +53,7 @@ type FlatConfig struct {
|
|||
TempComputeName *string `mapstructure:"temp_compute_name" required:"false" cty:"temp_compute_name"`
|
||||
TempResourceGroupName *string `mapstructure:"temp_resource_group_name" cty:"temp_resource_group_name"`
|
||||
BuildResourceGroupName *string `mapstructure:"build_resource_group_name" cty:"build_resource_group_name"`
|
||||
BuildKeyVaultName *string `mapstructure:"build_key_vault_name" cty:"build_key_vault_name"`
|
||||
PrivateVirtualNetworkWithPublicIp *bool `mapstructure:"private_virtual_network_with_public_ip" required:"false" cty:"private_virtual_network_with_public_ip"`
|
||||
VirtualNetworkName *string `mapstructure:"virtual_network_name" required:"false" cty:"virtual_network_name"`
|
||||
VirtualNetworkSubnetName *string `mapstructure:"virtual_network_subnet_name" required:"false" cty:"virtual_network_subnet_name"`
|
||||
|
@ -145,82 +146,83 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"shared_gallery_image_version_end_of_life_date": &hcldec.AttrSpec{Name: "shared_gallery_image_version_end_of_life_date", Type: cty.String, Required: false},
|
||||
"shared_image_gallery_replica_count": &hcldec.AttrSpec{Name: "shared_image_gallery_replica_count", Type: cty.Number, Required: false},
|
||||
"shared_gallery_image_version_exclude_from_latest": &hcldec.AttrSpec{Name: "shared_gallery_image_version_exclude_from_latest", Type: cty.Bool, Required: false},
|
||||
"image_publisher": &hcldec.AttrSpec{Name: "image_publisher", Type: cty.String, Required: false},
|
||||
"image_offer": &hcldec.AttrSpec{Name: "image_offer", Type: cty.String, Required: false},
|
||||
"image_sku": &hcldec.AttrSpec{Name: "image_sku", Type: cty.String, Required: false},
|
||||
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
|
||||
"image_url": &hcldec.AttrSpec{Name: "image_url", Type: cty.String, Required: false},
|
||||
"image_publisher": &hcldec.AttrSpec{Name: "image_publisher", Type: cty.String, Required: false},
|
||||
"image_offer": &hcldec.AttrSpec{Name: "image_offer", Type: cty.String, Required: false},
|
||||
"image_sku": &hcldec.AttrSpec{Name: "image_sku", Type: cty.String, Required: false},
|
||||
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
|
||||
"image_url": &hcldec.AttrSpec{Name: "image_url", Type: cty.String, Required: false},
|
||||
"custom_managed_image_name": &hcldec.AttrSpec{Name: "custom_managed_image_name", Type: cty.String, Required: false},
|
||||
"custom_managed_image_resource_group_name": &hcldec.AttrSpec{Name: "custom_managed_image_resource_group_name", Type: cty.String, Required: false},
|
||||
"custom_managed_image_name": &hcldec.AttrSpec{Name: "custom_managed_image_name", Type: cty.String, Required: false},
|
||||
"location": &hcldec.AttrSpec{Name: "location", Type: cty.String, Required: false},
|
||||
"vm_size": &hcldec.AttrSpec{Name: "vm_size", Type: cty.String, Required: false},
|
||||
"managed_image_resource_group_name": &hcldec.AttrSpec{Name: "managed_image_resource_group_name", Type: cty.String, Required: false},
|
||||
"managed_image_name": &hcldec.AttrSpec{Name: "managed_image_name", Type: cty.String, Required: false},
|
||||
"managed_image_storage_account_type": &hcldec.AttrSpec{Name: "managed_image_storage_account_type", Type: cty.String, Required: false},
|
||||
"managed_image_os_disk_snapshot_name": &hcldec.AttrSpec{Name: "managed_image_os_disk_snapshot_name", Type: cty.String, Required: false},
|
||||
"managed_image_data_disk_snapshot_prefix": &hcldec.AttrSpec{Name: "managed_image_data_disk_snapshot_prefix", Type: cty.String, Required: false},
|
||||
"managed_image_zone_resilient": &hcldec.AttrSpec{Name: "managed_image_zone_resilient", Type: cty.Bool, Required: false},
|
||||
"azure_tags": &hcldec.BlockAttrsSpec{TypeName: "azure_tags", ElementType: cty.String, Required: false},
|
||||
"resource_group_name": &hcldec.AttrSpec{Name: "resource_group_name", Type: cty.String, Required: false},
|
||||
"storage_account": &hcldec.AttrSpec{Name: "storage_account", Type: cty.String, Required: false},
|
||||
"temp_compute_name": &hcldec.AttrSpec{Name: "temp_compute_name", Type: cty.String, Required: false},
|
||||
"temp_resource_group_name": &hcldec.AttrSpec{Name: "temp_resource_group_name", Type: cty.String, Required: false},
|
||||
"build_resource_group_name": &hcldec.AttrSpec{Name: "build_resource_group_name", Type: cty.String, Required: false},
|
||||
"private_virtual_network_with_public_ip": &hcldec.AttrSpec{Name: "private_virtual_network_with_public_ip", Type: cty.Bool, Required: false},
|
||||
"virtual_network_name": &hcldec.AttrSpec{Name: "virtual_network_name", Type: cty.String, Required: false},
|
||||
"virtual_network_subnet_name": &hcldec.AttrSpec{Name: "virtual_network_subnet_name", Type: cty.String, Required: false},
|
||||
"virtual_network_resource_group_name": &hcldec.AttrSpec{Name: "virtual_network_resource_group_name", Type: cty.String, Required: false},
|
||||
"custom_data_file": &hcldec.AttrSpec{Name: "custom_data_file", Type: cty.String, Required: false},
|
||||
"plan_info": &hcldec.BlockSpec{TypeName: "plan_info", Nested: hcldec.ObjectSpec((*FlatPlanInformation)(nil).HCL2Spec())},
|
||||
"polling_duration_timeout": &hcldec.AttrSpec{Name: "polling_duration_timeout", Type: cty.String, Required: false},
|
||||
"os_type": &hcldec.AttrSpec{Name: "os_type", Type: cty.String, Required: false},
|
||||
"os_disk_size_gb": &hcldec.AttrSpec{Name: "os_disk_size_gb", Type: cty.Number, Required: false},
|
||||
"disk_additional_size": &hcldec.AttrSpec{Name: "disk_additional_size", Type: cty.List(cty.Number), Required: false},
|
||||
"disk_caching_type": &hcldec.AttrSpec{Name: "disk_caching_type", Type: cty.String, Required: false},
|
||||
"allowed_inbound_ip_addresses": &hcldec.AttrSpec{Name: "allowed_inbound_ip_addresses", Type: cty.List(cty.String), Required: false},
|
||||
"user_name": &hcldec.AttrSpec{Name: "user_name", Type: cty.String, Required: false},
|
||||
"password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
|
||||
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
|
||||
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
|
||||
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
|
||||
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
|
||||
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
|
||||
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
|
||||
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
|
||||
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
|
||||
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
|
||||
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
|
||||
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
|
||||
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
|
||||
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
|
||||
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
|
||||
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
|
||||
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
|
||||
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
|
||||
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
|
||||
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
|
||||
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
|
||||
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
|
||||
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
|
||||
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
|
||||
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
|
||||
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
|
||||
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false},
|
||||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"async_resourcegroup_delete": &hcldec.AttrSpec{Name: "async_resourcegroup_delete", Type: cty.Bool, Required: false},
|
||||
"location": &hcldec.AttrSpec{Name: "location", Type: cty.String, Required: false},
|
||||
"vm_size": &hcldec.AttrSpec{Name: "vm_size", Type: cty.String, Required: false},
|
||||
"managed_image_resource_group_name": &hcldec.AttrSpec{Name: "managed_image_resource_group_name", Type: cty.String, Required: false},
|
||||
"managed_image_name": &hcldec.AttrSpec{Name: "managed_image_name", Type: cty.String, Required: false},
|
||||
"managed_image_storage_account_type": &hcldec.AttrSpec{Name: "managed_image_storage_account_type", Type: cty.String, Required: false},
|
||||
"managed_image_os_disk_snapshot_name": &hcldec.AttrSpec{Name: "managed_image_os_disk_snapshot_name", Type: cty.String, Required: false},
|
||||
"managed_image_data_disk_snapshot_prefix": &hcldec.AttrSpec{Name: "managed_image_data_disk_snapshot_prefix", Type: cty.String, Required: false},
|
||||
"managed_image_zone_resilient": &hcldec.AttrSpec{Name: "managed_image_zone_resilient", Type: cty.Bool, Required: false},
|
||||
"azure_tags": &hcldec.BlockAttrsSpec{TypeName: "azure_tags", ElementType: cty.String, Required: false},
|
||||
"resource_group_name": &hcldec.AttrSpec{Name: "resource_group_name", Type: cty.String, Required: false},
|
||||
"storage_account": &hcldec.AttrSpec{Name: "storage_account", Type: cty.String, Required: false},
|
||||
"temp_compute_name": &hcldec.AttrSpec{Name: "temp_compute_name", Type: cty.String, Required: false},
|
||||
"temp_resource_group_name": &hcldec.AttrSpec{Name: "temp_resource_group_name", Type: cty.String, Required: false},
|
||||
"build_resource_group_name": &hcldec.AttrSpec{Name: "build_resource_group_name", Type: cty.String, Required: false},
|
||||
"build_key_vault_name": &hcldec.AttrSpec{Name: "build_key_vault_name", Type: cty.String, Required: false},
|
||||
"private_virtual_network_with_public_ip": &hcldec.AttrSpec{Name: "private_virtual_network_with_public_ip", Type: cty.Bool, Required: false},
|
||||
"virtual_network_name": &hcldec.AttrSpec{Name: "virtual_network_name", Type: cty.String, Required: false},
|
||||
"virtual_network_subnet_name": &hcldec.AttrSpec{Name: "virtual_network_subnet_name", Type: cty.String, Required: false},
|
||||
"virtual_network_resource_group_name": &hcldec.AttrSpec{Name: "virtual_network_resource_group_name", Type: cty.String, Required: false},
|
||||
"custom_data_file": &hcldec.AttrSpec{Name: "custom_data_file", Type: cty.String, Required: false},
|
||||
"plan_info": &hcldec.BlockSpec{TypeName: "plan_info", Nested: hcldec.ObjectSpec((*FlatPlanInformation)(nil).HCL2Spec())},
|
||||
"polling_duration_timeout": &hcldec.AttrSpec{Name: "polling_duration_timeout", Type: cty.String, Required: false},
|
||||
"os_type": &hcldec.AttrSpec{Name: "os_type", Type: cty.String, Required: false},
|
||||
"os_disk_size_gb": &hcldec.AttrSpec{Name: "os_disk_size_gb", Type: cty.Number, Required: false},
|
||||
"disk_additional_size": &hcldec.AttrSpec{Name: "disk_additional_size", Type: cty.List(cty.Number), Required: false},
|
||||
"disk_caching_type": &hcldec.AttrSpec{Name: "disk_caching_type", Type: cty.String, Required: false},
|
||||
"allowed_inbound_ip_addresses": &hcldec.AttrSpec{Name: "allowed_inbound_ip_addresses", Type: cty.List(cty.String), Required: false},
|
||||
"user_name": &hcldec.AttrSpec{Name: "user_name", Type: cty.String, Required: false},
|
||||
"password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
"ssh_port": &hcldec.AttrSpec{Name: "ssh_port", Type: cty.Number, Required: false},
|
||||
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
|
||||
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
|
||||
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
|
||||
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
|
||||
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
|
||||
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_pty": &hcldec.AttrSpec{Name: "ssh_pty", Type: cty.Bool, Required: false},
|
||||
"ssh_timeout": &hcldec.AttrSpec{Name: "ssh_timeout", Type: cty.String, Required: false},
|
||||
"ssh_agent_auth": &hcldec.AttrSpec{Name: "ssh_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_disable_agent_forwarding": &hcldec.AttrSpec{Name: "ssh_disable_agent_forwarding", Type: cty.Bool, Required: false},
|
||||
"ssh_handshake_attempts": &hcldec.AttrSpec{Name: "ssh_handshake_attempts", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_host": &hcldec.AttrSpec{Name: "ssh_bastion_host", Type: cty.String, Required: false},
|
||||
"ssh_bastion_port": &hcldec.AttrSpec{Name: "ssh_bastion_port", Type: cty.Number, Required: false},
|
||||
"ssh_bastion_agent_auth": &hcldec.AttrSpec{Name: "ssh_bastion_agent_auth", Type: cty.Bool, Required: false},
|
||||
"ssh_bastion_username": &hcldec.AttrSpec{Name: "ssh_bastion_username", Type: cty.String, Required: false},
|
||||
"ssh_bastion_password": &hcldec.AttrSpec{Name: "ssh_bastion_password", Type: cty.String, Required: false},
|
||||
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_file_transfer_method": &hcldec.AttrSpec{Name: "ssh_file_transfer_method", Type: cty.String, Required: false},
|
||||
"ssh_proxy_host": &hcldec.AttrSpec{Name: "ssh_proxy_host", Type: cty.String, Required: false},
|
||||
"ssh_proxy_port": &hcldec.AttrSpec{Name: "ssh_proxy_port", Type: cty.Number, Required: false},
|
||||
"ssh_proxy_username": &hcldec.AttrSpec{Name: "ssh_proxy_username", Type: cty.String, Required: false},
|
||||
"ssh_proxy_password": &hcldec.AttrSpec{Name: "ssh_proxy_password", Type: cty.String, Required: false},
|
||||
"ssh_keep_alive_interval": &hcldec.AttrSpec{Name: "ssh_keep_alive_interval", Type: cty.String, Required: false},
|
||||
"ssh_read_write_timeout": &hcldec.AttrSpec{Name: "ssh_read_write_timeout", Type: cty.String, Required: false},
|
||||
"ssh_remote_tunnels": &hcldec.AttrSpec{Name: "ssh_remote_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_local_tunnels": &hcldec.AttrSpec{Name: "ssh_local_tunnels", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_public_key": &hcldec.AttrSpec{Name: "ssh_public_key", Type: cty.List(cty.Number), Required: false},
|
||||
"ssh_private_key": &hcldec.AttrSpec{Name: "ssh_private_key", Type: cty.List(cty.Number), Required: false},
|
||||
"winrm_username": &hcldec.AttrSpec{Name: "winrm_username", Type: cty.String, Required: false},
|
||||
"winrm_password": &hcldec.AttrSpec{Name: "winrm_password", Type: cty.String, Required: false},
|
||||
"winrm_host": &hcldec.AttrSpec{Name: "winrm_host", Type: cty.String, Required: false},
|
||||
"winrm_port": &hcldec.AttrSpec{Name: "winrm_port", Type: cty.Number, Required: false},
|
||||
"winrm_timeout": &hcldec.AttrSpec{Name: "winrm_timeout", Type: cty.String, Required: false},
|
||||
"winrm_use_ssl": &hcldec.AttrSpec{Name: "winrm_use_ssl", Type: cty.Bool, Required: false},
|
||||
"winrm_insecure": &hcldec.AttrSpec{Name: "winrm_insecure", Type: cty.Bool, Required: false},
|
||||
"winrm_use_ntlm": &hcldec.AttrSpec{Name: "winrm_use_ntlm", Type: cty.Bool, Required: false},
|
||||
"async_resourcegroup_delete": &hcldec.AttrSpec{Name: "async_resourcegroup_delete", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package arm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/azure/common"
|
||||
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type StepCertificateInKeyVault struct {
|
||||
config *Config
|
||||
client common.AZVaultClientIface
|
||||
say func(message string)
|
||||
error func(e error)
|
||||
}
|
||||
|
||||
func NewStepCertificateInKeyVault(cli common.AZVaultClientIface, ui packer.Ui, config *Config) *StepCertificateInKeyVault {
|
||||
var step = &StepCertificateInKeyVault{
|
||||
client: cli,
|
||||
config: config,
|
||||
say: func(message string) { ui.Say(message) },
|
||||
error: func(e error) { ui.Error(e.Error()) },
|
||||
}
|
||||
|
||||
return step
|
||||
}
|
||||
|
||||
func (s *StepCertificateInKeyVault) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
s.say("Setting the certificate in the KeyVault...")
|
||||
var keyVaultName = state.Get(constants.ArmKeyVaultName).(string)
|
||||
|
||||
err := s.client.SetSecret(keyVaultName, DefaultSecretName, s.config.winrmCertificate)
|
||||
if err != nil {
|
||||
s.error(fmt.Errorf("Error setting winrm cert in custom keyvault: %s", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (*StepCertificateInKeyVault) Cleanup(multistep.StateBag) {
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package arm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
azcommon "github.com/hashicorp/packer/builder/azure/common"
|
||||
"github.com/hashicorp/packer/builder/azure/common/constants"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
func TestNewStepCertificateInKeyVault(t *testing.T) {
|
||||
cli := azcommon.MockAZVaultClient{}
|
||||
ui := &packer.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
}
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put(constants.ArmKeyVaultName, "testKeyVaultName")
|
||||
|
||||
config := &Config{
|
||||
winrmCertificate: "testCertificateString",
|
||||
}
|
||||
|
||||
certKVStep := NewStepCertificateInKeyVault(&cli, ui, config)
|
||||
stepAction := certKVStep.Run(context.TODO(), state)
|
||||
|
||||
if stepAction == multistep.ActionHalt {
|
||||
t.Fatalf("step should have succeeded.")
|
||||
}
|
||||
if !cli.SetSecretCalled {
|
||||
t.Fatalf("Step should have called SetSecret on Azure client.")
|
||||
}
|
||||
if cli.SetSecretCert != "testCertificateString" {
|
||||
t.Fatalf("Step should have read cert from winRMCertificate field on config.")
|
||||
}
|
||||
if cli.SetSecretVaultName != "testKeyVaultName" {
|
||||
t.Fatalf("step should have read keyvault name from state.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewStepCertificateInKeyVault_error(t *testing.T) {
|
||||
// Tell mock to return an error
|
||||
cli := azcommon.MockAZVaultClient{}
|
||||
cli.IsError = true
|
||||
|
||||
ui := &packer.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
}
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put(constants.ArmKeyVaultName, "testKeyVaultName")
|
||||
|
||||
config := &Config{
|
||||
winrmCertificate: "testCertificateString",
|
||||
}
|
||||
|
||||
certKVStep := NewStepCertificateInKeyVault(&cli, ui, config)
|
||||
stepAction := certKVStep.Run(context.TODO(), state)
|
||||
|
||||
if stepAction != multistep.ActionHalt {
|
||||
t.Fatalf("step should have failed.")
|
||||
}
|
||||
}
|
|
@ -44,9 +44,12 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(ctx context.Context, state
|
|||
}
|
||||
|
||||
if keyVaultDeploymentName, ok := state.GetOk(constants.ArmKeyVaultDeploymentName); ok {
|
||||
err = s.deleteDeploymentResources(ctx, keyVaultDeploymentName.(string), resourceGroupName)
|
||||
if err != nil {
|
||||
return err
|
||||
// Only delete if custom keyvault was not provided.
|
||||
if exists := state.Get(constants.ArmIsExistingKeyVault).(bool); exists {
|
||||
err = s.deleteDeploymentResources(ctx, keyVaultDeploymentName.(string), resourceGroupName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ const (
|
|||
ArmTags string = "arm.Tags"
|
||||
ArmVirtualMachineCaptureParameters string = "arm.VirtualMachineCaptureParameters"
|
||||
ArmIsExistingResourceGroup string = "arm.IsExistingResourceGroup"
|
||||
ArmIsExistingKeyVault string = "arm.IsExistingKeyVault"
|
||||
|
||||
ArmIsManagedImage string = "arm.IsManagedImage"
|
||||
ArmManagedImageResourceGroupName string = "arm.ManagedImageResourceGroupName"
|
||||
|
|
|
@ -16,6 +16,15 @@ const (
|
|||
AzureVaultApiVersion = "2016-10-01"
|
||||
)
|
||||
|
||||
// Enables us to test steps that access this cli
|
||||
type AZVaultClientIface interface {
|
||||
GetSecret(string, string) (*Secret, error)
|
||||
SetSecret(string, string, string) error
|
||||
DeletePreparer(string, string) (*http.Request, error)
|
||||
DeleteResponder(*http.Response) (autorest.Response, error)
|
||||
DeleteSender(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
type VaultClient struct {
|
||||
autorest.Client
|
||||
keyVaultEndpoint url.URL
|
||||
|
@ -54,7 +63,8 @@ func (client *VaultClient) GetSecret(vaultName, secretName string) (*Secret, err
|
|||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.getVaultUrl(vaultName)),
|
||||
autorest.WithPathParameters("/secrets/{secret-name}", p),
|
||||
autorest.WithQueryParameters(q))
|
||||
autorest.WithQueryParameters(q),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -86,6 +96,47 @@ func (client *VaultClient) GetSecret(vaultName, secretName string) (*Secret, err
|
|||
return &secret, nil
|
||||
}
|
||||
|
||||
func (client *VaultClient) SetSecret(vaultName, secretName string, secretValue string) error {
|
||||
p := map[string]interface{}{
|
||||
"secret-name": autorest.Encode("path", secretName),
|
||||
}
|
||||
q := map[string]interface{}{
|
||||
"api-version": AzureVaultApiVersion,
|
||||
}
|
||||
|
||||
jsonBody := fmt.Sprintf(`{"value": "%s"}`, secretValue)
|
||||
|
||||
req, err := autorest.Prepare(
|
||||
&http.Request{},
|
||||
autorest.AsPut(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.WithBaseURL(client.getVaultUrl(vaultName)),
|
||||
autorest.WithPathParameters("/secrets/{secret-name}", p),
|
||||
autorest.WithQueryParameters(q),
|
||||
autorest.WithString(jsonBody),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf(
|
||||
"Failed to set secret to %s/%s, HTTP status code=%d (%s)",
|
||||
vaultName,
|
||||
secretName,
|
||||
resp.StatusCode,
|
||||
http.StatusText(resp.StatusCode))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes the specified Azure key vault.
|
||||
//
|
||||
// resourceGroupName is the name of the Resource Group to which the vault belongs. vaultName is the name of the vault
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
type MockAZVaultClient struct {
|
||||
GetSecretCalled bool
|
||||
SetSecretCalled bool
|
||||
SetSecretVaultName string
|
||||
SetSecretSecretName string
|
||||
SetSecretCert string
|
||||
DeleteResponderCalled bool
|
||||
DeletePreparerCalled bool
|
||||
DeleteSenderCalled bool
|
||||
|
||||
IsError bool
|
||||
}
|
||||
|
||||
func (m *MockAZVaultClient) GetSecret(vaultName, secretName string) (*Secret, error) {
|
||||
m.GetSecretCalled = true
|
||||
var secret Secret
|
||||
return &secret, nil
|
||||
}
|
||||
|
||||
func (m *MockAZVaultClient) SetSecret(vaultName, secretName string, secretValue string) error {
|
||||
m.SetSecretCalled = true
|
||||
m.SetSecretVaultName = vaultName
|
||||
m.SetSecretSecretName = secretName
|
||||
m.SetSecretCert = secretValue
|
||||
|
||||
if m.IsError {
|
||||
return fmt.Errorf("generic error!!")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockAZVaultClient) DeletePreparer(resourceGroupName string, vaultName string) (*http.Request, error) {
|
||||
m.DeletePreparerCalled = true
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockAZVaultClient) DeleteResponder(resp *http.Response) (autorest.Response, error) {
|
||||
m.DeleteResponderCalled = true
|
||||
var result autorest.Response
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (m *MockAZVaultClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
m.DeleteSenderCalled = true
|
||||
return nil, nil
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
)
|
||||
|
||||
func TestGeneratedData_Put(t *testing.T) {
|
||||
|
|
|
@ -2,9 +2,9 @@ package lxc
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
|
|
@ -2,9 +2,9 @@ package lxd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
|
|
@ -25,6 +25,11 @@ func (a *NullArtifact) String() string {
|
|||
}
|
||||
|
||||
func (a *NullArtifact) State(name string) interface{} {
|
||||
if name == "generated_data" {
|
||||
return map[interface{}]interface{}{
|
||||
"ID": "Null",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
state := new(multistep.BasicStateBag)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
state.Put("instance_id", "Null")
|
||||
|
||||
// Run!
|
||||
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
|
||||
|
|
|
@ -2,9 +2,9 @@ package chroot
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SSHConfig contains the configuration for SSH communicator.
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
)
|
||||
|
||||
func testSSHConfig() *SSHConfig {
|
||||
|
|
|
@ -2,6 +2,7 @@ package qemu
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
)
|
||||
|
|
|
@ -2,9 +2,10 @@ package qemu
|
|||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStepHTTPIPDiscover_Run(t *testing.T) {
|
||||
|
|
|
@ -3,10 +3,11 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Step to discover the http ip
|
||||
|
|
|
@ -3,9 +3,10 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStepHTTPIPDiscover_Run(t *testing.T) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package clone
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package clone
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||
commonT "github.com/hashicorp/packer/builder/vsphere/common/testing"
|
||||
builderT "github.com/hashicorp/packer/helper/builder/testing"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCloneBuilderAcc_default(t *testing.T) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package clone
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
func TestCloneBuilder_ImplementsBuilder(t *testing.T) {
|
||||
|
|
|
@ -6,6 +6,7 @@ package clone
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
|
|
|
@ -6,6 +6,7 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -6,6 +6,7 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
)
|
||||
|
|
|
@ -6,6 +6,7 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -5,10 +5,11 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RunConfig struct {
|
||||
|
|
|
@ -7,11 +7,12 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ShutdownConfig struct {
|
||||
|
|
|
@ -2,6 +2,7 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -2,6 +2,7 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -6,11 +6,12 @@ package common
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type WaitIpConfig struct {
|
||||
|
|
|
@ -3,13 +3,14 @@ package testing
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"math/rand"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
func NewVMName() string {
|
||||
|
|
|
@ -2,6 +2,7 @@ package driver
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
|
|
|
@ -3,14 +3,15 @@ package driver
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/find"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/session"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Driver struct {
|
||||
|
|
|
@ -2,6 +2,7 @@ package driver
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
|
|
@ -2,6 +2,7 @@ package driver
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
|
|
@ -4,12 +4,13 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
type VirtualMachine struct {
|
||||
|
@ -43,6 +44,13 @@ type HardwareConfig struct {
|
|||
VideoRAM int64
|
||||
}
|
||||
|
||||
type NIC struct {
|
||||
Network string // "" for default network
|
||||
NetworkCard string // example: vmxnet3
|
||||
MacAddress string // set mac if want specific address
|
||||
Passthrough *bool // direct path i/o
|
||||
}
|
||||
|
||||
type CreateConfig struct {
|
||||
DiskThinProvisioned bool
|
||||
DiskControllerType string // example: "scsi", "pvscsi"
|
||||
|
@ -56,8 +64,7 @@ type CreateConfig struct {
|
|||
ResourcePool string
|
||||
Datastore string
|
||||
GuestOS string // example: otherGuest
|
||||
Network string // "" for default network
|
||||
NetworkCard string // example: vmxnet3
|
||||
NICs []NIC
|
||||
USBController bool
|
||||
Version uint // example: 10
|
||||
Firmware string // efi or bios
|
||||
|
@ -508,42 +515,56 @@ func addDisk(_ *Driver, devices object.VirtualDeviceList, config *CreateConfig)
|
|||
}
|
||||
|
||||
func addNetwork(d *Driver, devices object.VirtualDeviceList, config *CreateConfig) (object.VirtualDeviceList, error) {
|
||||
if len(config.NICs) == 0 {
|
||||
return nil, errors.New("no network adapters have been defined")
|
||||
}
|
||||
|
||||
var network object.NetworkReference
|
||||
if config.Network == "" {
|
||||
h, err := d.FindHost(config.Host)
|
||||
for _, nic := range config.NICs {
|
||||
if nic.Network == "" {
|
||||
h, err := d.FindHost(config.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i, err := h.Info("network")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(i.Network) > 1 {
|
||||
return nil, fmt.Errorf("Host has multiple networks. Specify it explicitly")
|
||||
}
|
||||
|
||||
network = object.NewNetwork(d.client.Client, i.Network[0])
|
||||
} else {
|
||||
var err error
|
||||
network, err = d.finder.Network(d.ctx, nic.Network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
backing, err := network.EthernetCardBackingInfo(d.ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i, err := h.Info("network")
|
||||
device, err := object.EthernetCardTypes().CreateEthernetCard(nic.NetworkCard, backing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(i.Network) > 1 {
|
||||
return nil, fmt.Errorf("Host has multiple networks. Specify it explicitly")
|
||||
card := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard()
|
||||
if nic.MacAddress != "" {
|
||||
card.AddressType = string(types.VirtualEthernetCardMacTypeManual)
|
||||
card.MacAddress = nic.MacAddress
|
||||
}
|
||||
card.UptCompatibilityEnabled = nic.Passthrough
|
||||
|
||||
network = object.NewNetwork(d.client.Client, i.Network[0])
|
||||
} else {
|
||||
var err error
|
||||
network, err = d.finder.Network(d.ctx, config.Network)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices = append(devices, device)
|
||||
}
|
||||
|
||||
backing, err := network.EthernetCardBackingInfo(d.ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
device, err := object.EthernetCardTypes().CreateEthernetCard(config.NetworkCard, backing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return append(devices, device), nil
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) AddCdrom(controllerType string, isoPath string) error {
|
||||
|
|
|
@ -2,6 +2,7 @@ package driver
|
|||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
|
@ -51,6 +52,23 @@ func (vm *VirtualMachine) CreateCdrom(c *types.VirtualController) (*types.Virtua
|
|||
return device, nil
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) RemoveCdroms() error {
|
||||
devices, err := vm.Devices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cdroms := devices.SelectByType((*types.VirtualCdrom)(nil))
|
||||
if err = vm.RemoveDevice(true, cdroms...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sata := devices.SelectByType((*types.VirtualAHCIController)(nil))
|
||||
if err = vm.RemoveDevice(true, sata...); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) EjectCdroms() error {
|
||||
devices, err := vm.Devices()
|
||||
if err != nil {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package driver
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"golang.org/x/mobile/event/key"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type KeyInput struct {
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
)
|
||||
|
||||
|
|
|
@ -121,7 +121,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
}
|
||||
|
||||
steps = append(steps,
|
||||
&StepRemoveCDRom{},
|
||||
&StepRemoveCDRom{
|
||||
Config: &b.config.RemoveCDRomConfig,
|
||||
},
|
||||
&common.StepCreateSnapshot{
|
||||
CreateSnapshot: b.config.CreateSnapshot,
|
||||
},
|
||||
|
|
|
@ -2,13 +2,14 @@ package iso
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
commonT "github.com/hashicorp/packer/builder/vsphere/common/testing"
|
||||
builderT "github.com/hashicorp/packer/helper/builder/testing"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestISOBuilderAcc_default(t *testing.T) {
|
||||
|
|
|
@ -24,6 +24,7 @@ type Config struct {
|
|||
packerCommon.ISOConfig `mapstructure:",squash"`
|
||||
|
||||
CDRomConfig `mapstructure:",squash"`
|
||||
RemoveCDRomConfig `mapstructure:",squash"`
|
||||
FloppyConfig `mapstructure:",squash"`
|
||||
common.RunConfig `mapstructure:",squash"`
|
||||
BootConfig `mapstructure:",squash"`
|
||||
|
|
|
@ -32,6 +32,7 @@ type FlatConfig struct {
|
|||
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
|
||||
Network *string `mapstructure:"network" cty:"network"`
|
||||
NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
|
||||
NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"`
|
||||
USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"`
|
||||
Notes *string `mapstructure:"notes" cty:"notes"`
|
||||
VMName *string `mapstructure:"vm_name" cty:"vm_name"`
|
||||
|
@ -61,6 +62,7 @@ type FlatConfig struct {
|
|||
TargetExtension *string `mapstructure:"iso_target_extension" cty:"iso_target_extension"`
|
||||
CdromType *string `mapstructure:"cdrom_type" cty:"cdrom_type"`
|
||||
ISOPaths []string `mapstructure:"iso_paths" cty:"iso_paths"`
|
||||
RemoveCdrom *bool `mapstructure:"remove_cdrom" cty:"remove_cdrom"`
|
||||
FloppyIMGPath *string `mapstructure:"floppy_img_path" cty:"floppy_img_path"`
|
||||
FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files"`
|
||||
FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs"`
|
||||
|
@ -151,6 +153,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"disk_thin_provisioned": &hcldec.AttrSpec{Name: "disk_thin_provisioned", Type: cty.Bool, Required: false},
|
||||
"network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false},
|
||||
"network_card": &hcldec.AttrSpec{Name: "network_card", Type: cty.String, Required: false},
|
||||
"network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())},
|
||||
"usb_controller": &hcldec.AttrSpec{Name: "usb_controller", Type: cty.Bool, Required: false},
|
||||
"notes": &hcldec.AttrSpec{Name: "notes", Type: cty.String, Required: false},
|
||||
"vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false},
|
||||
|
@ -180,6 +183,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"iso_target_extension": &hcldec.AttrSpec{Name: "iso_target_extension", Type: cty.String, Required: false},
|
||||
"cdrom_type": &hcldec.AttrSpec{Name: "cdrom_type", Type: cty.String, Required: false},
|
||||
"iso_paths": &hcldec.AttrSpec{Name: "iso_paths", Type: cty.List(cty.String), Required: false},
|
||||
"remove_cdrom": &hcldec.AttrSpec{Name: "remove_cdrom", Type: cty.Bool, Required: false},
|
||||
"floppy_img_path": &hcldec.AttrSpec{Name: "floppy_img_path", Type: cty.String, Required: false},
|
||||
"floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false},
|
||||
"floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false},
|
||||
|
|
|
@ -6,6 +6,7 @@ package iso
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -6,6 +6,7 @@ package iso
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -3,18 +3,19 @@ package iso
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
packerCommon "github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"golang.org/x/mobile/event/key"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
packerCommon "github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"golang.org/x/mobile/event/key"
|
||||
)
|
||||
|
||||
type BootConfig struct {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type CreateConfig
|
||||
//go:generate mapstructure-to-hcl2 -type NIC,CreateConfig
|
||||
|
||||
package iso
|
||||
|
||||
|
@ -13,6 +13,17 @@ import (
|
|||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type NIC struct {
|
||||
// Set network VM will be connected to.
|
||||
Network string `mapstructure:"network"`
|
||||
// Set VM network card type. Example `vmxnet3`.
|
||||
NetworkCard string `mapstructure:"network_card" required:"true"`
|
||||
// Set network card MAC address
|
||||
MacAddress string `mapstructure:"mac_address"`
|
||||
// Enable DirectPath I/O passthrough
|
||||
Passthrough *bool `mapstructure:"passthrough"`
|
||||
}
|
||||
|
||||
type CreateConfig struct {
|
||||
// Set VM hardware version. Defaults to the most current VM hardware
|
||||
// version supported by vCenter. See
|
||||
|
@ -35,6 +46,8 @@ type CreateConfig struct {
|
|||
Network string `mapstructure:"network"`
|
||||
// Set VM network card type. Example `vmxnet3`.
|
||||
NetworkCard string `mapstructure:"network_card"`
|
||||
// Network adapters
|
||||
NICs []NIC `mapstructure:"network_adapters"`
|
||||
// Create USB controller for virtual machine. Defaults to `false`.
|
||||
USBController bool `mapstructure:"usb_controller"`
|
||||
// VM notes.
|
||||
|
@ -83,6 +96,23 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
}
|
||||
|
||||
ui.Say("Creating VM...")
|
||||
|
||||
// add network/network card an the first nic for backwards compatibility in the type is defined
|
||||
var networkCards []driver.NIC
|
||||
if s.Config.NetworkCard != "" {
|
||||
networkCards = append(networkCards, driver.NIC{
|
||||
NetworkCard: s.Config.NetworkCard,
|
||||
Network: s.Config.Network})
|
||||
}
|
||||
for _, nic := range s.Config.NICs {
|
||||
networkCards = append(networkCards, driver.NIC{
|
||||
Network: nic.Network,
|
||||
NetworkCard: nic.NetworkCard,
|
||||
MacAddress: nic.MacAddress,
|
||||
Passthrough: nic.Passthrough,
|
||||
})
|
||||
}
|
||||
|
||||
vm, err = d.CreateVM(&driver.CreateConfig{
|
||||
DiskThinProvisioned: s.Config.DiskThinProvisioned,
|
||||
DiskControllerType: s.Config.DiskControllerType,
|
||||
|
@ -94,8 +124,7 @@ func (s *StepCreateVM) Run(_ context.Context, state multistep.StateBag) multiste
|
|||
ResourcePool: s.Location.ResourcePool,
|
||||
Datastore: s.Location.Datastore,
|
||||
GuestOS: s.Config.GuestOSType,
|
||||
Network: s.Config.Network,
|
||||
NetworkCard: s.Config.NetworkCard,
|
||||
NICs: networkCards,
|
||||
USBController: s.Config.USBController,
|
||||
Version: s.Config.Version,
|
||||
Firmware: s.Config.Firmware,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "mapstructure-to-hcl2 -type CreateConfig"; DO NOT EDIT.
|
||||
// Code generated by "mapstructure-to-hcl2 -type NIC,CreateConfig"; DO NOT EDIT.
|
||||
package iso
|
||||
|
||||
import (
|
||||
|
@ -9,16 +9,17 @@ import (
|
|||
// FlatCreateConfig is an auto-generated flat version of CreateConfig.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatCreateConfig struct {
|
||||
Version *uint `mapstructure:"vm_version" cty:"vm_version"`
|
||||
GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"`
|
||||
Firmware *string `mapstructure:"firmware" cty:"firmware"`
|
||||
DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"`
|
||||
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
|
||||
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
|
||||
Network *string `mapstructure:"network" cty:"network"`
|
||||
NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
|
||||
USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"`
|
||||
Notes *string `mapstructure:"notes" cty:"notes"`
|
||||
Version *uint `mapstructure:"vm_version" cty:"vm_version"`
|
||||
GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"`
|
||||
Firmware *string `mapstructure:"firmware" cty:"firmware"`
|
||||
DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"`
|
||||
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
|
||||
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
|
||||
Network *string `mapstructure:"network" cty:"network"`
|
||||
NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
|
||||
NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"`
|
||||
USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"`
|
||||
Notes *string `mapstructure:"notes" cty:"notes"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatCreateConfig.
|
||||
|
@ -41,8 +42,36 @@ func (*FlatCreateConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"disk_thin_provisioned": &hcldec.AttrSpec{Name: "disk_thin_provisioned", Type: cty.Bool, Required: false},
|
||||
"network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false},
|
||||
"network_card": &hcldec.AttrSpec{Name: "network_card", Type: cty.String, Required: false},
|
||||
"network_adapters": &hcldec.BlockListSpec{TypeName: "network_adapters", Nested: hcldec.ObjectSpec((*FlatNIC)(nil).HCL2Spec())},
|
||||
"usb_controller": &hcldec.AttrSpec{Name: "usb_controller", Type: cty.Bool, Required: false},
|
||||
"notes": &hcldec.AttrSpec{Name: "notes", Type: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FlatNIC is an auto-generated flat version of NIC.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatNIC struct {
|
||||
Network *string `mapstructure:"network" cty:"network"`
|
||||
NetworkCard *string `mapstructure:"network_card" required:"true" cty:"network_card"`
|
||||
MacAddress *string `mapstructure:"mac_address" cty:"mac_address"`
|
||||
Passthrough *bool `mapstructure:"passthrough" cty:"passthrough"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatNIC.
|
||||
// FlatNIC is an auto-generated flat version of NIC.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*NIC) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { return new(FlatNIC) }
|
||||
|
||||
// HCL2Spec returns the hcl spec of a NIC.
|
||||
// This spec is used by HCL to read the fields of NIC.
|
||||
// The decoded values from this spec will then be applied to a FlatNIC.
|
||||
func (*FlatNIC) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"network": &hcldec.AttrSpec{Name: "network", Type: cty.String, Required: false},
|
||||
"network_card": &hcldec.AttrSpec{Name: "network_card", Type: cty.String, Required: false},
|
||||
"mac_address": &hcldec.AttrSpec{Name: "mac_address", Type: cty.String, Required: false},
|
||||
"passthrough": &hcldec.AttrSpec{Name: "passthrough", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@ package iso
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type StepRemoteUpload struct {
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type RemoveCDRomConfig
|
||||
|
||||
package iso
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type StepRemoveCDRom struct{}
|
||||
type RemoveCDRomConfig struct {
|
||||
// Remove CD-ROM devices from template. Defaults to `false`.
|
||||
RemoveCdrom bool `mapstructure:"remove_cdrom"`
|
||||
}
|
||||
|
||||
type StepRemoveCDRom struct {
|
||||
Config *RemoveCDRomConfig
|
||||
}
|
||||
|
||||
func (s *StepRemoveCDRom) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
@ -20,6 +31,15 @@ func (s *StepRemoveCDRom) Run(_ context.Context, state multistep.StateBag) multi
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if s.Config.RemoveCdrom == true {
|
||||
ui.Say("Deleting CD-ROM drives...")
|
||||
err := vm.RemoveCdroms()
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// Code generated by "mapstructure-to-hcl2 -type RemoveCDRomConfig"; DO NOT EDIT.
|
||||
package iso
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatRemoveCDRomConfig is an auto-generated flat version of RemoveCDRomConfig.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatRemoveCDRomConfig struct {
|
||||
RemoveCdrom *bool `mapstructure:"remove_cdrom" cty:"remove_cdrom"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatRemoveCDRomConfig.
|
||||
// FlatRemoveCDRomConfig is an auto-generated flat version of RemoveCDRomConfig.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*RemoveCDRomConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatRemoveCDRomConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a RemoveCDRomConfig.
|
||||
// This spec is used by HCL to read the fields of RemoveCDRomConfig.
|
||||
// The decoded values from this spec will then be applied to a FlatRemoveCDRomConfig.
|
||||
func (*FlatRemoveCDRomConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"remove_cdrom": &hcldec.AttrSpec{Name: "remove_cdrom", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -2,6 +2,7 @@ package iso
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
|
|
@ -41,6 +41,8 @@ type Config struct {
|
|||
// is an alternative method to authenticate to Yandex.Cloud. Alternatively you may set environment variable
|
||||
// YC_SERVICE_ACCOUNT_KEY_FILE.
|
||||
ServiceAccountKeyFile string `mapstructure:"service_account_key_file" required:"false"`
|
||||
// Service account identifier to assign to instance
|
||||
ServiceAccountID string `mapstructure:"service_account_id" required:"false"`
|
||||
// OAuth token to use to authenticate to Yandex.Cloud. Alternatively you may set
|
||||
// value by environment variable YC_TOKEN.
|
||||
Token string `mapstructure:"token" required:"true"`
|
||||
|
|
|
@ -59,6 +59,7 @@ type FlatConfig struct {
|
|||
Endpoint *string `mapstructure:"endpoint" required:"false" cty:"endpoint"`
|
||||
FolderID *string `mapstructure:"folder_id" required:"true" cty:"folder_id"`
|
||||
ServiceAccountKeyFile *string `mapstructure:"service_account_key_file" required:"false" cty:"service_account_key_file"`
|
||||
ServiceAccountID *string `mapstructure:"service_account_id" required:"false" cty:"service_account_id"`
|
||||
Token *string `mapstructure:"token" required:"true" cty:"token"`
|
||||
DiskName *string `mapstructure:"disk_name" required:"false" cty:"disk_name"`
|
||||
DiskSizeGb *int `mapstructure:"disk_size_gb" required:"false" cty:"disk_size_gb"`
|
||||
|
@ -153,6 +154,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"endpoint": &hcldec.AttrSpec{Name: "endpoint", Type: cty.String, Required: false},
|
||||
"folder_id": &hcldec.AttrSpec{Name: "folder_id", Type: cty.String, Required: false},
|
||||
"service_account_key_file": &hcldec.AttrSpec{Name: "service_account_key_file", Type: cty.String, Required: false},
|
||||
"service_account_id": &hcldec.AttrSpec{Name: "service_account_id", Type: cty.String, Required: false},
|
||||
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
|
||||
"disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false},
|
||||
"disk_size_gb": &hcldec.AttrSpec{Name: "disk_size_gb", Type: cty.Number, Required: false},
|
||||
|
|
|
@ -205,6 +205,10 @@ runcmd:
|
|||
},
|
||||
}
|
||||
|
||||
if config.ServiceAccountID != "" {
|
||||
req.ServiceAccountId = config.ServiceAccountID
|
||||
}
|
||||
|
||||
if config.UseIPv6 {
|
||||
req.NetworkInterfaceSpecs[0].PrimaryV6AddressSpec = &compute.PrimaryAddressSpec{}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/types"
|
||||
"io"
|
||||
"log"
|
||||
|
@ -39,6 +38,7 @@ import (
|
|||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
"golang.org/x/tools/imports"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -189,7 +189,7 @@ func main() {
|
|||
log.Fatalf("os.Create: %v", err)
|
||||
}
|
||||
|
||||
_, err = outputFile.Write(goFmt(out.Bytes()))
|
||||
_, err = outputFile.Write(goFmt(outputFile.Name(), out.Bytes()))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to write file: %v", err)
|
||||
}
|
||||
|
@ -575,8 +575,8 @@ func ToSnakeCase(str string) string {
|
|||
return strings.ToLower(snake)
|
||||
}
|
||||
|
||||
func goFmt(b []byte) []byte {
|
||||
fb, err := format.Source(b)
|
||||
func goFmt(filename string, b []byte) []byte {
|
||||
fb, err := imports.Process(filename, b, nil)
|
||||
if err != nil {
|
||||
log.Printf("formatting err: %v", err)
|
||||
return b
|
||||
|
|
|
@ -60,19 +60,20 @@ func main() {
|
|||
}
|
||||
|
||||
fields := structDecl.Fields.List
|
||||
sourcePath := filepath.ToSlash(paths[1])
|
||||
header := Struct{
|
||||
SourcePath: paths[1],
|
||||
SourcePath: sourcePath,
|
||||
Name: typeSpec.Name.Name,
|
||||
Filename: "_" + typeSpec.Name.Name + ".html.md",
|
||||
Header: typeDecl.Doc.Text(),
|
||||
}
|
||||
required := Struct{
|
||||
SourcePath: paths[1],
|
||||
SourcePath: sourcePath,
|
||||
Name: typeSpec.Name.Name,
|
||||
Filename: "_" + typeSpec.Name.Name + "-required.html.md",
|
||||
}
|
||||
notRequired := Struct{
|
||||
SourcePath: paths[1],
|
||||
SourcePath: sourcePath,
|
||||
Name: typeSpec.Name.Name,
|
||||
Filename: "_" + typeSpec.Name.Name + "-not-required.html.md",
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/hashicorp/packer/builder/file"
|
||||
|
|
|
@ -111,6 +111,33 @@ func TestBuildOnlyFileMultipleFlags(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuildProvisionAndPosProcessWithBuildVariablesSharing(t *testing.T) {
|
||||
c := &BuildCommand{
|
||||
Meta: testMetaFile(t),
|
||||
}
|
||||
|
||||
args := []string{
|
||||
filepath.Join(testFixture("build-variable-sharing"), "template.json"),
|
||||
}
|
||||
|
||||
files := []string{
|
||||
"provisioner.Null.txt",
|
||||
"post-processor.Null.txt",
|
||||
}
|
||||
|
||||
defer cleanup(files...)
|
||||
|
||||
if code := c.Run(args); code != 0 {
|
||||
fatalCommand(t, c.Meta)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if !fileExists(f) {
|
||||
t.Errorf("Expected to find %s", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildEverything(t *testing.T) {
|
||||
c := &BuildCommand{
|
||||
Meta: testMetaFile(t),
|
||||
|
@ -231,7 +258,7 @@ func testMetaFile(t *testing.T) Meta {
|
|||
}
|
||||
}
|
||||
|
||||
func cleanup() {
|
||||
func cleanup(moreFiles ...string) {
|
||||
os.RemoveAll("chocolate.txt")
|
||||
os.RemoveAll("vanilla.txt")
|
||||
os.RemoveAll("cherry.txt")
|
||||
|
@ -245,6 +272,9 @@ func cleanup() {
|
|||
os.RemoveAll("lilas.txt")
|
||||
os.RemoveAll("campanules.txt")
|
||||
os.RemoveAll("ducky.txt")
|
||||
for _, file := range moreFiles {
|
||||
os.RemoveAll(file)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildCommand_ParseArgs(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"builders": [
|
||||
{
|
||||
"name": "chocolate",
|
||||
"type": "null",
|
||||
"communicator": "none"
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell-local",
|
||||
"inline": [
|
||||
"echo hi > provisioner.{{ build `ID`}}.txt"
|
||||
]
|
||||
}
|
||||
],
|
||||
"post-processors": [
|
||||
{
|
||||
"type": "shell-local",
|
||||
"inline": [
|
||||
"echo hi > post-processor.{{ build `ID`}}.txt"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,15 +3,12 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
getter "github.com/hashicorp/go-getter"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
)
|
||||
|
||||
|
@ -106,7 +103,7 @@ type ISOConfig struct {
|
|||
TargetExtension string `mapstructure:"iso_target_extension"`
|
||||
}
|
||||
|
||||
func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs []error) {
|
||||
func (c *ISOConfig) Prepare(*interpolate.Context) (warnings []string, errs []error) {
|
||||
if len(c.ISOUrls) != 0 && c.RawSingleISOUrl != "" {
|
||||
errs = append(
|
||||
errs, errors.New("Only one of iso_url or iso_urls must be specified"))
|
||||
|
@ -159,27 +156,13 @@ func (c *ISOConfig) Prepare(ctx *interpolate.Context) (warnings []string, errs [
|
|||
errs = append(errs, fmt.Errorf("A checksum must be specified"))
|
||||
}
|
||||
if c.ISOChecksumType == "file" {
|
||||
u, err := url.Parse(c.ISOUrls[0])
|
||||
url := c.ISOChecksum
|
||||
if c.ISOChecksumURL != "" {
|
||||
url = c.ISOChecksumURL
|
||||
}
|
||||
cksum, err := defaultGetterClient.ChecksumFromFile(context.TODO(), url, c.ISOUrls[0])
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("error parsing URL <%s>: %s",
|
||||
c.ISOUrls[0], err))
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Printf("get working directory: %v", err)
|
||||
// here we ignore the error in case the
|
||||
// working directory is not needed.
|
||||
}
|
||||
gc := getter.Client{
|
||||
Dst: "no-op",
|
||||
Src: u.String(),
|
||||
Pwd: wd,
|
||||
Dir: false,
|
||||
Getters: getter.Getters,
|
||||
}
|
||||
cksum, err := gc.ChecksumFromFile(c.ISOChecksumURL, u)
|
||||
if cksum == nil || err != nil {
|
||||
errs = append(errs, fmt.Errorf("Couldn't extract checksum from checksum file"))
|
||||
errs = append(errs, fmt.Errorf("Couldn't extract checksum from checksum file: %v", err))
|
||||
} else {
|
||||
c.ISOChecksumType = cksum.Type
|
||||
c.ISOChecksum = hex.EncodeToString(cksum.Value)
|
||||
|
|
|
@ -5,7 +5,6 @@ package shell_local
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
// "log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
|
||||
getter "github.com/hashicorp/go-getter"
|
||||
urlhelper "github.com/hashicorp/go-getter/helper/url"
|
||||
getter "github.com/hashicorp/go-getter/v2"
|
||||
urlhelper "github.com/hashicorp/go-getter/v2/helper/url"
|
||||
"github.com/hashicorp/packer/common/filelock"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
|
@ -52,6 +52,8 @@ type StepDownload struct {
|
|||
Extension string
|
||||
}
|
||||
|
||||
var defaultGetterClient = getter.Client{}
|
||||
|
||||
func (s *StepDownload) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
if len(s.Url) == 0 {
|
||||
log.Printf("No URLs were provided to Step Download. Continuing...")
|
||||
|
@ -96,24 +98,6 @@ func (s *StepDownload) Run(ctx context.Context, state multistep.StateBag) multis
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
var (
|
||||
getters = getter.Getters
|
||||
)
|
||||
|
||||
func init() {
|
||||
if runtime.GOOS == "windows" {
|
||||
getters["file"] = &getter.FileGetter{
|
||||
// always copy local files instead of symlinking to fix GH-7534. The
|
||||
// longer term fix for this would be to change the go-getter so that it
|
||||
// can leave the source file where it is & tell us where it is.
|
||||
Copy: true,
|
||||
}
|
||||
getters["smb"] = &getter.FileGetter{
|
||||
Copy: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StepDownload) download(ctx context.Context, ui packer.Ui, source string) (string, error) {
|
||||
if runtime.GOOS == "windows" {
|
||||
// Check that the user specified a UNC path, and promote it to an smb:// uri.
|
||||
|
@ -208,20 +192,19 @@ func (s *StepDownload) download(ctx context.Context, ui packer.Ui, source string
|
|||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Trying %s", u.String()))
|
||||
gc := getter.Client{
|
||||
Ctx: ctx,
|
||||
req := &getter.Request{
|
||||
Dst: targetPath,
|
||||
Src: src,
|
||||
ProgressListener: ui,
|
||||
Pwd: wd,
|
||||
Dir: false,
|
||||
Getters: getters,
|
||||
Mode: getter.ModeFile,
|
||||
Inplace: true,
|
||||
}
|
||||
|
||||
switch err := gc.Get(); err.(type) {
|
||||
switch op, err := defaultGetterClient.Get(ctx, req); err.(type) {
|
||||
case nil: // success !
|
||||
ui.Say(fmt.Sprintf("%s => %s", u.String(), targetPath))
|
||||
return targetPath, nil
|
||||
ui.Say(fmt.Sprintf("%s => %s", u.String(), op.Dst))
|
||||
return op.Dst, nil
|
||||
case *getter.ChecksumError:
|
||||
ui.Say(fmt.Sprintf("Checksum did not match, removing %s", targetPath))
|
||||
if err := os.Remove(targetPath); err != nil {
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"context"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
|
@ -16,8 +15,9 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
urlhelper "github.com/hashicorp/go-getter/helper/url"
|
||||
urlhelper "github.com/hashicorp/go-getter/v2/helper/url"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/packer/tmp"
|
||||
)
|
||||
|
||||
|
@ -74,7 +74,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Url: []string{abs(t, "./test-fixtures/root/another.txt")}},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(abs(t, "./test-fixtures/root/another.txt")),
|
||||
toSha1(abs(t, "./test-fixtures/root/another.txt")) + ".lock",
|
||||
},
|
||||
},
|
||||
|
@ -82,7 +81,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Url: []string{abs(t, "./test-fixtures/root//another.txt")}},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(abs(t, "./test-fixtures/root//another.txt")),
|
||||
toSha1(abs(t, "./test-fixtures/root//another.txt")) + ".lock",
|
||||
},
|
||||
},
|
||||
|
@ -90,7 +88,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Url: []string{abs(t, "./test-fixtures/root/another.txt")}, ChecksumType: "none"},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(abs(t, "./test-fixtures/root/another.txt")),
|
||||
toSha1(abs(t, "./test-fixtures/root/another.txt")) + ".lock",
|
||||
},
|
||||
},
|
||||
|
@ -159,7 +156,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Extension: "txt", Url: []string{"./test-fixtures/root/another.txt?checksum=" + cs["/root/another.txt"]}},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/another.txt"]) + ".txt",
|
||||
toSha1(cs["/root/another.txt"]) + ".txt.lock",
|
||||
},
|
||||
},
|
||||
|
@ -167,7 +163,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Extension: "txt", Url: []string{"./test-fixtures/root/another.txt?"}, Checksum: cs["/root/another.txt"]},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/another.txt"]) + ".txt",
|
||||
toSha1(cs["/root/another.txt"]) + ".txt.lock",
|
||||
},
|
||||
},
|
||||
|
@ -175,7 +170,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Extension: "txt", Url: []string{"./test-fixtures/root/another.txt?"}, ChecksumType: "sha1", Checksum: cs["/root/another.txt"]},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/another.txt"]) + ".txt",
|
||||
toSha1(cs["/root/another.txt"]) + ".txt.lock",
|
||||
},
|
||||
},
|
||||
|
@ -183,7 +177,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Extension: "txt", Url: []string{abs(t, "./test-fixtures/root/another.txt") + "?checksum=" + cs["/root/another.txt"]}},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/another.txt"]) + ".txt",
|
||||
toSha1(cs["/root/another.txt"]) + ".txt.lock",
|
||||
},
|
||||
},
|
||||
|
@ -191,7 +184,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Extension: "txt", Url: []string{abs(t, "./test-fixtures/root/another.txt") + "?"}, Checksum: cs["/root/another.txt"]},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/another.txt"]) + ".txt",
|
||||
toSha1(cs["/root/another.txt"]) + ".txt.lock",
|
||||
},
|
||||
},
|
||||
|
@ -199,7 +191,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
fields{Extension: "txt", Url: []string{abs(t, "./test-fixtures/root/another.txt") + "?"}, ChecksumType: "sha1", Checksum: cs["/root/another.txt"]},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/another.txt"]) + ".txt",
|
||||
toSha1(cs["/root/another.txt"]) + ".txt.lock",
|
||||
},
|
||||
},
|
||||
|
@ -214,7 +205,6 @@ func TestStepDownload_Run(t *testing.T) {
|
|||
},
|
||||
multistep.ActionContinue,
|
||||
[]string{
|
||||
toSha1(cs["/root/basic.txt"]),
|
||||
toSha1(cs["/root/basic.txt"]) + ".lock",
|
||||
},
|
||||
},
|
||||
|
@ -268,36 +258,33 @@ func TestStepDownload_download(t *testing.T) {
|
|||
// Abs path with extension provided
|
||||
step.TargetPath = "./packer"
|
||||
step.Extension = "ova"
|
||||
path, err := step.download(context.TODO(), ui, "./test-fixtures/root/basic.txt")
|
||||
_, err := step.download(context.TODO(), ui, "./test-fixtures/root/basic.txt")
|
||||
if err != nil {
|
||||
t.Fatalf("Bad: non expected error %s", err.Error())
|
||||
}
|
||||
if filepath.Ext(path) != "."+step.Extension {
|
||||
t.Fatalf("bad: path should contain extension %s but it was %s", step.Extension, filepath.Ext(path))
|
||||
}
|
||||
// because of the inplace option; the result file will not be renamed
|
||||
// sha.ova.
|
||||
os.RemoveAll(step.TargetPath)
|
||||
|
||||
// Abs path with no extension provided
|
||||
step.TargetPath = "./packer"
|
||||
step.Extension = ""
|
||||
path, err = step.download(context.TODO(), ui, "./test-fixtures/root/basic.txt")
|
||||
_, err = step.download(context.TODO(), ui, "./test-fixtures/root/basic.txt")
|
||||
if err != nil {
|
||||
t.Fatalf("Bad: non expected error %s", err.Error())
|
||||
}
|
||||
if filepath.Ext(path) != ".iso" {
|
||||
t.Fatalf("bad: path should contain extension %s but it was .iso", step.Extension)
|
||||
}
|
||||
// because of the inplace option; the result file will not be renamed
|
||||
// sha.ova.
|
||||
os.RemoveAll(step.TargetPath)
|
||||
|
||||
// Path with file
|
||||
step.TargetPath = "./packer/file.iso"
|
||||
path, err = step.download(context.TODO(), ui, "./test-fixtures/root/basic.txt")
|
||||
_, err = step.download(context.TODO(), ui, "./test-fixtures/root/basic.txt")
|
||||
if err != nil {
|
||||
t.Fatalf("Bad: non expected error %s", err.Error())
|
||||
}
|
||||
if path != "./packer/file.iso" {
|
||||
t.Fatalf("bad: path should be ./packer/file.iso but it was %s", path)
|
||||
}
|
||||
// because of the inplace option; the result file will not be renamed
|
||||
// sha.ova.
|
||||
os.RemoveAll(step.TargetPath)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/helper/communicator"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@ package common
|
|||
|
||||
// Imports for determining terminal information across platforms
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// posix api
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package fix
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
type FixerAmazonTemporarySecurityCIDRs struct{}
|
||||
|
|
6
go.mod
6
go.mod
|
@ -72,7 +72,8 @@ require (
|
|||
github.com/hashicorp/go-cty-funcs/encoding v0.0.0-20200203151509-c92509f48b18
|
||||
github.com/hashicorp/go-cty-funcs/filesystem v0.0.0-20200203151509-c92509f48b18
|
||||
github.com/hashicorp/go-cty-funcs/uuid v0.0.0-20200203151509-c92509f48b18
|
||||
github.com/hashicorp/go-getter v1.3.1-0.20190906090232-a0f878cb75da
|
||||
github.com/hashicorp/go-getter v1.3.1-0.20190906090232-a0f878cb75da // indirect
|
||||
github.com/hashicorp/go-getter/v2 v2.0.0-20200206160058-e2a28063d6e7
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/hashicorp/go-oracle-terraform v0.0.0-20181016190316-007121241b79
|
||||
github.com/hashicorp/go-retryablehttp v0.5.2 // indirect
|
||||
|
@ -111,6 +112,7 @@ require (
|
|||
github.com/mitchellh/go-fs v0.0.0-20180402234041-7b48fa161ea7
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed
|
||||
github.com/mitchellh/gox v1.0.1 // indirect
|
||||
github.com/mitchellh/iochan v1.0.0
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180111000720-b4575eea38cc
|
||||
github.com/mitchellh/panicwrap v0.0.0-20170106182340-fce601fe5557
|
||||
|
@ -163,7 +165,7 @@ require (
|
|||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||
golang.org/x/tools v0.0.0-20191203051722-db047d72ee39
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa
|
||||
google.golang.org/api v0.14.0
|
||||
google.golang.org/appengine v1.6.5 // indirect
|
||||
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
|
||||
|
|
14
go.sum
14
go.sum
|
@ -239,6 +239,8 @@ github.com/hashicorp/go-cty-funcs/uuid v0.0.0-20200203151509-c92509f48b18 h1:CxY
|
|||
github.com/hashicorp/go-cty-funcs/uuid v0.0.0-20200203151509-c92509f48b18/go.mod h1:QFbv9KeSic7KIgfOYbUW02G4LxOf3Fh9Ylm4n174LUQ=
|
||||
github.com/hashicorp/go-getter v1.3.1-0.20190906090232-a0f878cb75da h1:HAasZmyRrb7/paYuww5RfVwY3wkFpsbMNYwBxOSZquY=
|
||||
github.com/hashicorp/go-getter v1.3.1-0.20190906090232-a0f878cb75da/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
|
||||
github.com/hashicorp/go-getter/v2 v2.0.0-20200206160058-e2a28063d6e7 h1:ODZKizgWGz4diUEZwCgf8qgIn/D+qVW/JOdVVV/z7k8=
|
||||
github.com/hashicorp/go-getter/v2 v2.0.0-20200206160058-e2a28063d6e7/go.mod h1:jlmxRRjTpY0KdWrV1Uq38GUVskrjIZUrjOAybo0OArw=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
|
@ -261,6 +263,7 @@ github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1
|
|||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
|
||||
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
|
||||
|
@ -368,6 +371,8 @@ github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaC
|
|||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
|
||||
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
|
||||
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 v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
|
@ -500,6 +505,7 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
|
@ -527,6 +533,8 @@ golang.org/x/mobile v0.0.0-20191130191448-5c0e7e404af8 h1:9w7mvrikkrG9zFfEJfuFe0
|
|||
golang.org/x/mobile v0.0.0-20191130191448-5c0e7e404af8/go.mod h1:p895TfNkDgPEmEQrNiOtIl3j98d/tGU95djDj7NfyjQ=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -620,9 +628,11 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191203051722-db047d72ee39 h1:zARK4PTmTfx1BC6iKP21qIRjz0nFzFj4ZAlbUy6Q6pM=
|
||||
golang.org/x/tools v0.0.0-20191203051722-db047d72ee39/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa h1:5E4dL8+NgFOgjwbTKz+OOEGGhP+ectTmF842l6KjupQ=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
|
|
|
@ -49,7 +49,7 @@ func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl
|
|||
return postProcessor, diags
|
||||
}
|
||||
|
||||
func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContext) (packer.PostProcessor, hcl.Diagnostics) {
|
||||
func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.PostProcessor, hcl.Diagnostics) {
|
||||
// ProvisionerBlock represents a detected but unparsed provisioner
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
|
@ -64,7 +64,7 @@ func (p *Parser) startPostProcessor(pp *PostProcessorBlock, ectx *hcl.EvalContex
|
|||
}
|
||||
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, ectx, postProcessor)
|
||||
diags = append(diags, moreDiags...)
|
||||
err = postProcessor.Configure(flatProvisinerCfg)
|
||||
err = postProcessor.Configure(flatProvisinerCfg, generatedVars)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/gohcl"
|
||||
"github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
|
@ -47,7 +46,7 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia
|
|||
return provisioner, diags
|
||||
}
|
||||
|
||||
func (p *Parser) startProvisioner(pb *ProvisionerBlock, ectx *hcl.EvalContext, generatedVars []string) (packer.Provisioner, hcl.Diagnostics) {
|
||||
func (p *Parser) startProvisioner(pb *ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) (packer.Provisioner, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
provisioner, err := p.ProvisionersSchemas.Start(pb.PType)
|
||||
|
@ -67,22 +66,10 @@ func (p *Parser) startProvisioner(pb *ProvisionerBlock, ectx *hcl.EvalContext, g
|
|||
// manipulate generatedVars from builder to add to the interfaces being
|
||||
// passed to the provisioner Prepare()
|
||||
|
||||
// If the builder has provided a list of to-be-generated variables that
|
||||
// should be made accessible to provisioners, pass that list into
|
||||
// the provisioner prepare() so that the provisioner can appropriately
|
||||
// validate user input against what will become available. Otherwise,
|
||||
// only pass the default variables, using the basic placeholder data.
|
||||
generatedPlaceholderMap := packer.BasicPlaceholderData()
|
||||
if generatedVars != nil {
|
||||
for _, k := range generatedVars {
|
||||
generatedPlaceholderMap[k] = fmt.Sprintf("Generated_%s. "+
|
||||
common.PlaceholderMsg, k)
|
||||
}
|
||||
}
|
||||
// configs := make([]interface{}, 2)
|
||||
// configs = append(, flatProvisionerCfg)
|
||||
// configs = append(configs, generatedPlaceholderMap)
|
||||
err = provisioner.Prepare(flatProvisionerCfg, generatedPlaceholderMap)
|
||||
// configs = append(configs, generatedVars)
|
||||
err = provisioner.Prepare(flatProvisionerCfg, generatedVars)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package hcl2template
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
@ -42,7 +44,7 @@ func (cfg *PackerConfig) EvalContext() *hcl.EvalContext {
|
|||
|
||||
// getCoreBuildProvisioners takes a list of provisioner block, starts according
|
||||
// provisioners and sends parsed HCL2 over to it.
|
||||
func (p *Parser) getCoreBuildProvisioners(blocks []*ProvisionerBlock, ectx *hcl.EvalContext, generatedVars []string) ([]packer.CoreBuildProvisioner, hcl.Diagnostics) {
|
||||
func (p *Parser) getCoreBuildProvisioners(blocks []*ProvisionerBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildProvisioner, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
res := []packer.CoreBuildProvisioner{}
|
||||
for _, pb := range blocks {
|
||||
|
@ -62,11 +64,11 @@ func (p *Parser) getCoreBuildProvisioners(blocks []*ProvisionerBlock, ectx *hcl.
|
|||
|
||||
// getCoreBuildProvisioners takes a list of post processor block, starts
|
||||
// according provisioners and sends parsed HCL2 over to it.
|
||||
func (p *Parser) getCoreBuildPostProcessors(blocks []*PostProcessorBlock, ectx *hcl.EvalContext) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
|
||||
func (p *Parser) getCoreBuildPostProcessors(blocks []*PostProcessorBlock, ectx *hcl.EvalContext, generatedVars map[string]string) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
res := []packer.CoreBuildPostProcessor{}
|
||||
for _, ppb := range blocks {
|
||||
postProcessor, moreDiags := p.startPostProcessor(ppb, ectx)
|
||||
postProcessor, moreDiags := p.startPostProcessor(ppb, ectx, generatedVars)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
continue
|
||||
|
@ -104,12 +106,26 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics)
|
|||
if moreDiags.HasErrors() {
|
||||
continue
|
||||
}
|
||||
provisioners, moreDiags := p.getCoreBuildProvisioners(build.ProvisionerBlocks, cfg.EvalContext(), generatedVars)
|
||||
|
||||
// If the builder has provided a list of to-be-generated variables that
|
||||
// should be made accessible to provisioners, pass that list into
|
||||
// the provisioner prepare() so that the provisioner can appropriately
|
||||
// validate user input against what will become available. Otherwise,
|
||||
// only pass the default variables, using the basic placeholder data.
|
||||
generatedPlaceholderMap := packer.BasicPlaceholderData()
|
||||
if generatedVars != nil {
|
||||
for _, k := range generatedVars {
|
||||
generatedPlaceholderMap[k] = fmt.Sprintf("Build_%s. "+
|
||||
common.PlaceholderMsg, k)
|
||||
}
|
||||
}
|
||||
|
||||
provisioners, moreDiags := p.getCoreBuildProvisioners(build.ProvisionerBlocks, cfg.EvalContext(), generatedPlaceholderMap)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
continue
|
||||
}
|
||||
postProcessors, moreDiags := p.getCoreBuildPostProcessors(build.PostProcessors, cfg.EvalContext())
|
||||
postProcessors, moreDiags := p.getCoreBuildPostProcessors(build.PostProcessors, cfg.EvalContext(), generatedPlaceholderMap)
|
||||
pps := [][]packer.CoreBuildPostProcessor{}
|
||||
if len(postProcessors) > 0 {
|
||||
pps = [][]packer.CoreBuildPostProcessor{postProcessors}
|
||||
|
@ -124,6 +140,7 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics)
|
|||
Builder: builder,
|
||||
Provisioners: provisioners,
|
||||
PostProcessors: pps,
|
||||
Prepared: true,
|
||||
}
|
||||
res = append(res, pcb)
|
||||
}
|
||||
|
|
|
@ -57,8 +57,9 @@ func TestParser_complete(t *testing.T) {
|
|||
false, false,
|
||||
[]packer.Build{
|
||||
&packer.CoreBuild{
|
||||
Type: "virtualbox-iso",
|
||||
Builder: basicMockBuilder,
|
||||
Type: "virtualbox-iso",
|
||||
Prepared: true,
|
||||
Builder: basicMockBuilder,
|
||||
Provisioners: []packer.CoreBuildProvisioner{
|
||||
{
|
||||
PType: "shell",
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package ssh
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer/communicator/ssh"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/communicator/ssh"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -97,6 +97,9 @@ type CoreBuild struct {
|
|||
TemplatePath string
|
||||
Variables map[string]string
|
||||
|
||||
// Indicates whether the build is already initialized before calling Prepare(..)
|
||||
Prepared bool
|
||||
|
||||
debug bool
|
||||
force bool
|
||||
onError string
|
||||
|
@ -132,6 +135,13 @@ func (b *CoreBuild) Name() string {
|
|||
// and any hooks. This _must_ be called prior to Run. The parameter is the
|
||||
// overrides for the variables within the template (if any).
|
||||
func (b *CoreBuild) Prepare() (warn []string, err error) {
|
||||
// For HCL2 templates, the builder and hooks are initialized when the template is parsed.
|
||||
// Calling Prepare(...) is not necessary
|
||||
if b.Prepared {
|
||||
b.prepareCalled = true
|
||||
return
|
||||
}
|
||||
|
||||
b.l.Lock()
|
||||
defer b.l.Unlock()
|
||||
|
||||
|
|
|
@ -88,6 +88,17 @@ func TestBuild_Prepare(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuild_Prepare_SkipWhenBuilderAlreadyInitialized(t *testing.T) {
|
||||
build := testBuild()
|
||||
builder := build.Builder.(*MockBuilder)
|
||||
|
||||
build.Prepared = true
|
||||
build.Prepare()
|
||||
if builder.PrepareCalled {
|
||||
t.Fatal("should not be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuild_Prepare_Twice(t *testing.T) {
|
||||
build := testBuild()
|
||||
warn, err := build.Prepare()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue