mirror of
https://github.com/hashicorp/packer.git
synced 2026-03-27 12:53:31 -04:00
Merge pull request #13467 from hashicorp/karthik/release_1.14.2
release 1.14.2.
This commit is contained in:
commit
e703473a9b
25 changed files with 388 additions and 57 deletions
7
.github/workflows/acceptance-test.yml
vendored
7
.github/workflows/acceptance-test.yml
vendored
|
|
@ -6,6 +6,8 @@
|
|||
name: "Acceptance Test"
|
||||
|
||||
on:
|
||||
# workflow_dispatch allows manual triggering of the workflow
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Runs against the default branch every day at midnight
|
||||
- cron: "0 0 * * *"
|
||||
|
|
@ -54,11 +56,14 @@ jobs:
|
|||
role-duration-seconds: 3600
|
||||
- name: Install gotestsum
|
||||
run: go install gotest.tools/gotestsum@latest
|
||||
|
||||
# we set the ACC_TEST_BUILDERS="amazon-ebs" since we want to test against the amazon-ebs tests (e.g. Powershell
|
||||
# provisioner acceptance tests)
|
||||
- name: Run acceptance tests per module
|
||||
run: |
|
||||
mkdir -p /tmp/test-results
|
||||
make dev
|
||||
PACKER_ACC=1 gotestsum --format=short-verbose --junitfile /tmp/test-results/gotestsum-report.xml -- -timeout=120m -p 2 $(go list ./... | grep -v inspec | grep -v profitbricks | grep -v oneandone)
|
||||
ACC_TEST_BUILDERS="amazon-ebs" PACKER_ACC=1 gotestsum --format=short-verbose --junitfile /tmp/test-results/gotestsum-report.xml -- -timeout=120m -p 2 $(go list ./... | grep -v inspec | grep -v profitbricks | grep -v oneandone)
|
||||
# Send a slack notification if either job defined above fails
|
||||
slack-notify:
|
||||
permissions:
|
||||
|
|
|
|||
41
CHANGELOG.md
41
CHANGELOG.md
|
|
@ -1,3 +1,44 @@
|
|||
# 📦 Changelog
|
||||
## 1.14.2 (September 9, 2025)
|
||||
## ✨ Features
|
||||
- **HCP Certificate Authentication Support** – by @JenGoldstrich ([#13435](https://github.com/hashicorp/packer/pull/13435))
|
||||
Adds support for the `HCP_CRED_FILE` environment variable and removes restrictions on `HCP_CLIENT_ID` and `HCP_CLIENT_SECRET` when connecting builds to an HCP Packer registry.
|
||||
|
||||
- **Upgrade Node.js to v22** – by @LeahMarieBush ([#13450](https://github.com/hashicorp/packer/pull/13450))
|
||||
Updates the Node.js version used for Packer website builds.
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
- **fix(winrm): catch cmd err from winrm** – by @anurag5sh in ([#298](https://github.com/hashicorp/packer-plugin-sdk/pull/298))
|
||||
Improved reliability by catching WinRM remote shell failures during provisioning
|
||||
- **PowerShell wrapper cleanup** – by @kp2099 ([#13451](https://github.com/hashicorp/packer/pull/13451))
|
||||
Removed the unused `$result` variable from the wrapper string.
|
||||
- **fix tests for shell and shell-local** – by @kp2099 in ([#300](https://github.com/hashicorp/packer-plugin-sdk/pull/300))
|
||||
Acceptance test fixes for shell and shell-local
|
||||
|
||||
---
|
||||
|
||||
## 🛠 Improvements
|
||||
- Added workflow-dispatch and set `PACKER_ACC_BUILDERS` for acceptance tests – by @kp2099 ([#13444](https://github.com/hashicorp/packer/pull/13444))
|
||||
- Improved spacing in `hcl2template` error messages – by @sbraz ([#13453](https://github.com/hashicorp/packer/pull/13453))
|
||||
- Added callouts for HashiCorp-maintained plugins moving to [releases.hashicorp.com](https://releases.hashicorp.com) – by @BrianMMcClain ([#13438](https://github.com/hashicorp/packer/pull/13438))
|
||||
|
||||
---
|
||||
|
||||
## 📦 Dependencies
|
||||
- Bump `github.com/ulikunitz/xz` from **0.5.10 → 0.5.14** – by @dependabot ([#13459](https://github.com/hashicorp/packer/pull/13459))
|
||||
- Bump `golang.org/x/oauth2` from **0.13.0 → 0.27.0** – by @dependabot ([#13460](https://github.com/hashicorp/packer/pull/13460))
|
||||
- Bump `github.com/ulikunitz/xz` from **0.5.10 → 0.5.15** – by @kp2099 ([#13461](https://github.com/hashicorp/packer/pull/13461))
|
||||
- Bump `github.com/hashicorp/packer-plugin-sdk` from **0.6.2 → 0.6.3** – by @kp2099 ([#13462](https://github.com/hashicorp/packer/pull/13462))
|
||||
|
||||
---
|
||||
|
||||
## 👩💻 New Contributors
|
||||
- @LeahMarieBush made their first contribution in [#13450](https://github.com/hashicorp/packer/pull/13450) 🎉
|
||||
|
||||
|
||||
|
||||
## 1.14.1 (August 5, 2025)
|
||||
|
||||
### BUG FIXES:
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -23,7 +23,7 @@ require (
|
|||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hashicorp/hcl/v2 v2.19.1
|
||||
github.com/hashicorp/hcp-sdk-go v0.136.0
|
||||
github.com/hashicorp/packer-plugin-sdk v0.6.2
|
||||
github.com/hashicorp/packer-plugin-sdk v0.6.3
|
||||
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869
|
||||
github.com/klauspost/compress v1.13.6
|
||||
github.com/klauspost/pgzip v1.2.5
|
||||
|
|
@ -40,7 +40,7 @@ require (
|
|||
github.com/pkg/sftp v1.13.2 // indirect
|
||||
github.com/posener/complete v1.2.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/ulikunitz/xz v0.5.10
|
||||
github.com/ulikunitz/xz v0.5.15
|
||||
github.com/zclconf/go-cty v1.13.3
|
||||
github.com/zclconf/go-cty-yaml v1.0.1
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -304,6 +304,8 @@ github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR
|
|||
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.6.2 h1:XRIJTcHa9AN13ZvVjL+RpwxEz+yYT7qJ5PA2REViJZ0=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.6.2/go.mod h1:mOuey53XeLIIpdOQnREjEBYCndipO7piU+EJAstQq1k=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.6.3 h1:WEZQxQVvcoM0KoeuhJQ/hIPd0g117jwnf//vXZoNAbk=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.6.3/go.mod h1:mOuey53XeLIIpdOQnREjEBYCndipO7piU+EJAstQq1k=
|
||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||
github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU=
|
||||
|
|
@ -532,6 +534,8 @@ github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxW
|
|||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
|
||||
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block, cfg *PackerConfig) (*BuildB
|
|||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Invalid " + sourceLabel + " reference",
|
||||
Detail: "A " + sourceLabel + " type is made of three parts that are" +
|
||||
Detail: "A " + sourceLabel + " type is made of three parts that are " +
|
||||
"split by a dot `.`; each part must start with a letter and " +
|
||||
"may contain only letters, digits, underscores, and dashes." +
|
||||
"may contain only letters, digits, underscores, and dashes. " +
|
||||
"A valid source reference looks like: `source.type.name`",
|
||||
Subject: block.DefRange.Ptr(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -34,13 +34,19 @@ type Client struct {
|
|||
}
|
||||
|
||||
// NewClient returns an authenticated client to a HCP Packer Registry.
|
||||
// Client authentication requires the following environment variables be set HCP_CLIENT_ID and HCP_CLIENT_SECRET.
|
||||
// Upon error a HCPClientError will be returned.
|
||||
func NewClient() (*Client, error) {
|
||||
if !env.HasHCPCredentials() {
|
||||
hasAuth, err := env.HasHCPAuth()
|
||||
if err != nil {
|
||||
return nil, &ClientError{
|
||||
StatusCode: InvalidClientConfig,
|
||||
Err: fmt.Errorf("the client authentication requires both %s and %s environment variables to be set", env.HCPClientID, env.HCPClientSecret),
|
||||
Err: fmt.Errorf("Failed to check for HCP auth, error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
if !hasAuth {
|
||||
return nil, &ClientError{
|
||||
StatusCode: InvalidClientConfig,
|
||||
Err: fmt.Errorf("HCP Authentication not configured, either set an HCP Client ID and secret using the environment variables %s and %s, place an HCP credential file in the default path (%s), or at a different path specified in the %s environment variable.", env.HCPClientID, env.HCPClientSecret, env.HCPDefaultCredFilePathFull, env.HCPCredFile),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ type DeprecatedClient struct {
|
|||
}
|
||||
|
||||
// NewDeprecatedClient returns an authenticated client to a HCP Packer Registry.
|
||||
// Client authentication requires the following environment variables be set HCP_CLIENT_ID and HCP_CLIENT_SECRET.
|
||||
// Upon error a HCPClientError will be returned.
|
||||
func NewDeprecatedClient() (*DeprecatedClient, error) {
|
||||
// Use NewClient to validate HCP configuration provided by user.
|
||||
|
|
|
|||
64
internal/hcp/env/env.go
vendored
64
internal/hcp/env/env.go
vendored
|
|
@ -5,10 +5,28 @@
|
|||
package env
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func HasHCPAuth() (bool, error) {
|
||||
// Client crendential authentication requires the following environment variables be set; `HCP_CLIENT_ID` and `HCP_CLIENT_SECRET`.
|
||||
hasClientCredentials := HasHCPClientCredentials()
|
||||
// Client certificate authentication requires a valid HCP certificate file placed in either the default location (~/.config/hcp/cred_file.json) or at a location specified in the `HCP_CRED_FILE` env var
|
||||
hasCertificate, err := HasHCPCertificateFile()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if hasClientCredentials && hasCertificate {
|
||||
fmt.Printf("HCP Client Credentials (HCP_CLIENT_ID/HCP_CLIENT_SECRET environment variables) and certificate (HCP_CRED_FILE environment variable, or certificate located at default path (%s) are both supplied, only one is required. The HCP SDK will determine which authentication mechanism to configure here, it is reccomended to only configure one authentication method", HCPDefaultCredFilePathFull)
|
||||
}
|
||||
return (hasClientCredentials || hasCertificate), nil
|
||||
}
|
||||
|
||||
func HasProjectID() bool {
|
||||
return hasEnvVar(HCPProjectID)
|
||||
}
|
||||
|
|
@ -37,7 +55,7 @@ func hasEnvVar(varName string) bool {
|
|||
return val != ""
|
||||
}
|
||||
|
||||
func HasHCPCredentials() bool {
|
||||
func HasHCPClientCredentials() bool {
|
||||
checks := []func() bool{
|
||||
HasClientID,
|
||||
HasClientSecret,
|
||||
|
|
@ -52,6 +70,39 @@ func HasHCPCredentials() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func HasHCPCertificateFile() (bool, error) {
|
||||
envVarCredFile, _ := os.LookupEnv(HCPCredFile)
|
||||
var envVarCertExists bool
|
||||
var err error
|
||||
if envVarCredFile != "" {
|
||||
envVarCertExists, err = fileExists(envVarCredFile)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
// Get the user's home directory.
|
||||
userHome, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to retrieve user's home directory path: %v", err)
|
||||
}
|
||||
|
||||
// builds file path ~/.config/hcp/cred_file.json, if we don't parse the home directory os.Stat can't find the default credential path
|
||||
defaultCredFilePath := filepath.Join(userHome, HCPDefaultCredFilePath, HCPDefaultCredFile)
|
||||
log.Printf("Checking for default HCP credential file at path %s", defaultCredFilePath)
|
||||
defaultPathCertExists, err := fileExists(defaultCredFilePath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
log.Printf("Default file found status - %t", defaultPathCertExists)
|
||||
if envVarCertExists && defaultPathCertExists {
|
||||
fmt.Println("A HCP credential file was found at the default path, and an HCP_CRED_FILE was specified, the HCP SDK will use the HCP_CRED_FILE")
|
||||
}
|
||||
if envVarCertExists || defaultPathCertExists {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func IsHCPDisabled() bool {
|
||||
hcp, ok := os.LookupEnv(HCPPackerRegistry)
|
||||
return ok && strings.ToLower(hcp) == "off" || hcp == "0"
|
||||
|
|
@ -62,3 +113,14 @@ func IsHCPExplicitelyEnabled() bool {
|
|||
_, ok := os.LookupEnv(HCPPackerRegistry)
|
||||
return ok && !IsHCPDisabled()
|
||||
}
|
||||
|
||||
func fileExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true, nil // Path exists, no error
|
||||
}
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return false, nil // Path does not exist
|
||||
}
|
||||
return false, err // Another error occurred
|
||||
}
|
||||
|
|
|
|||
166
internal/hcp/env/env_test.go
vendored
166
internal/hcp/env/env_test.go
vendored
|
|
@ -4,6 +4,8 @@
|
|||
package env
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -50,3 +52,167 @@ func Test_IsHCPDisabled(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
func Test_HasHCPAuth(t *testing.T) {
|
||||
origClientID := os.Getenv(HCPClientID)
|
||||
origClientSecret := os.Getenv(HCPClientSecret)
|
||||
origCredFile := os.Getenv(HCPCredFile)
|
||||
origDefaultCredFilePath := ""
|
||||
|
||||
// Save and restore default cred file at ~/.config/hcp/cred_file.json
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get home dir: %v", err)
|
||||
}
|
||||
credDir := filepath.Join(homeDir, HCPDefaultCredFilePath)
|
||||
defaultCredPath := filepath.Join(credDir, HCPDefaultCredFile)
|
||||
|
||||
if _, err := os.Stat(defaultCredPath); err == nil {
|
||||
tmpFile, err := os.CreateTemp("", "orig_cred_file.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file for original cred file: %v", err)
|
||||
}
|
||||
tmpFile.Close()
|
||||
origDefaultCredFilePath = tmpFile.Name()
|
||||
if err := os.Rename(defaultCredPath, origDefaultCredFilePath); err != nil {
|
||||
t.Fatalf("failed to move original cred file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type setupFunc func(t *testing.T)
|
||||
|
||||
tmpCredFile := func(t *testing.T) string {
|
||||
f, err := os.CreateTemp("", "cred_file.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file: %v", err)
|
||||
}
|
||||
f.Close()
|
||||
t.Cleanup(func() { os.Remove(f.Name()) })
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
tmpDefaultCredFile := func(t *testing.T) string {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get home dir: %v", err)
|
||||
}
|
||||
credDir := filepath.Join(homeDir, HCPDefaultCredFilePath)
|
||||
os.MkdirAll(credDir, 0755)
|
||||
credPath := filepath.Join(credDir, HCPDefaultCredFile)
|
||||
f, err := os.Create(credPath)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create default cred file: %v", err)
|
||||
}
|
||||
f.Close()
|
||||
t.Cleanup(func() { os.Remove(credPath) })
|
||||
return credPath
|
||||
}
|
||||
|
||||
tcs := []struct {
|
||||
name string
|
||||
setup setupFunc
|
||||
want bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "neither credentials nor certificate present",
|
||||
setup: func(t *testing.T) {
|
||||
os.Unsetenv(HCPClientID)
|
||||
os.Unsetenv(HCPClientSecret)
|
||||
os.Unsetenv(HCPCredFile)
|
||||
},
|
||||
want: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "only credentials present",
|
||||
setup: func(t *testing.T) {
|
||||
os.Unsetenv(HCPCredFile)
|
||||
os.Setenv(HCPClientID, "foo")
|
||||
os.Setenv(HCPClientSecret, "bar")
|
||||
},
|
||||
want: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "only certificate present via env var",
|
||||
setup: func(t *testing.T) {
|
||||
os.Unsetenv(HCPClientID)
|
||||
os.Unsetenv(HCPClientSecret)
|
||||
os.Setenv(HCPCredFile, tmpCredFile(t))
|
||||
},
|
||||
want: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "only certificate present via default path",
|
||||
setup: func(t *testing.T) {
|
||||
os.Unsetenv(HCPClientID)
|
||||
os.Unsetenv(HCPClientSecret)
|
||||
os.Unsetenv(HCPCredFile)
|
||||
tmpDefaultCredFile(t)
|
||||
},
|
||||
want: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "both credentials and certificate present",
|
||||
setup: func(t *testing.T) {
|
||||
os.Setenv(HCPClientID, "foo")
|
||||
os.Setenv(HCPClientSecret, "bar")
|
||||
os.Setenv(HCPCredFile, tmpCredFile(t))
|
||||
},
|
||||
want: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "certificate file doesn't exist",
|
||||
setup: func(t *testing.T) {
|
||||
os.Unsetenv(HCPClientID)
|
||||
os.Unsetenv(HCPClientSecret)
|
||||
os.Setenv(HCPCredFile, "/my_fake_file") // Invalid path to trigger error
|
||||
},
|
||||
want: false,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tc.setup(t)
|
||||
got, err := HasHCPAuth()
|
||||
if got != tc.want {
|
||||
t.Fatalf("expected %v, got %v", tc.want, got)
|
||||
}
|
||||
if tc.wantErr && err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
if !tc.wantErr && err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Restore original env vars
|
||||
if origClientID != "" {
|
||||
os.Setenv(HCPClientID, origClientID)
|
||||
} else {
|
||||
os.Unsetenv(HCPClientID)
|
||||
}
|
||||
if origClientSecret != "" {
|
||||
os.Setenv(HCPClientSecret, origClientSecret)
|
||||
} else {
|
||||
os.Unsetenv(HCPClientSecret)
|
||||
}
|
||||
if origCredFile != "" {
|
||||
os.Setenv(HCPCredFile, origCredFile)
|
||||
} else {
|
||||
os.Unsetenv(HCPCredFile)
|
||||
}
|
||||
os.Remove(defaultCredPath)
|
||||
// Restore original default cred file if it was present before test run
|
||||
if origDefaultCredFilePath != "" {
|
||||
if err := os.Rename(origDefaultCredFilePath, defaultCredPath); err != nil {
|
||||
t.Fatalf("failed to replace temp default cred file: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
internal/hcp/env/variables.go
vendored
18
internal/hcp/env/variables.go
vendored
|
|
@ -4,11 +4,15 @@
|
|||
package env
|
||||
|
||||
const (
|
||||
HCPClientID = "HCP_CLIENT_ID"
|
||||
HCPClientSecret = "HCP_CLIENT_SECRET"
|
||||
HCPProjectID = "HCP_PROJECT_ID"
|
||||
HCPOrganizationID = "HCP_ORGANIZATION_ID"
|
||||
HCPPackerRegistry = "HCP_PACKER_REGISTRY"
|
||||
HCPPackerBucket = "HCP_PACKER_BUCKET_NAME"
|
||||
HCPPackerBuildFingerprint = "HCP_PACKER_BUILD_FINGERPRINT"
|
||||
HCPClientID = "HCP_CLIENT_ID"
|
||||
HCPClientSecret = "HCP_CLIENT_SECRET"
|
||||
HCPCredFile = "HCP_CRED_FILE"
|
||||
HCPDefaultCredFilePath = ".config/hcp/"
|
||||
HCPDefaultCredFilePathFull = "~/.config/hcp/cred_file.json"
|
||||
HCPDefaultCredFile = "cred_file.json"
|
||||
HCPProjectID = "HCP_PROJECT_ID"
|
||||
HCPOrganizationID = "HCP_ORGANIZATION_ID"
|
||||
HCPPackerRegistry = "HCP_PACKER_REGISTRY"
|
||||
HCPPackerBucket = "HCP_PACKER_BUCKET_NAME"
|
||||
HCPPackerBuildFingerprint = "HCP_PACKER_BUILD_FINGERPRINT"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -63,13 +63,17 @@ func IsHCPEnabled(cfg packer.Handler) bool {
|
|||
func createConfiguredBucket(templateDir string, opts ...bucketConfigurationOpts) (*Bucket, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
if !env.HasHCPCredentials() {
|
||||
hasAuth, err := env.HasHCPAuth()
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "HCP authentication information required",
|
||||
Detail: fmt.Sprintf("The client authentication requires both %s and %s environment "+
|
||||
"variables to be set for authenticating with HCP.",
|
||||
env.HCPClientID,
|
||||
env.HCPClientSecret),
|
||||
Summary: "HCP authentication check failed",
|
||||
Detail: fmt.Sprintf("Failed to check for HCP authentication, error: %s", err.Error()),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
} else if !hasAuth {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "HCP authentication information required",
|
||||
Detail: fmt.Sprintf("HCP Authentication not configured, either set an HCP Client ID and secret using the environment variables %s and %s, place an HCP credential file in the default path (%s), or at a different path specified in the %s environment variable.", env.HCPClientID, env.HCPClientSecret, env.HCPDefaultCredFilePath, env.HCPCredFile),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
}
|
||||
|
|
@ -94,7 +98,7 @@ func createConfiguredBucket(templateDir string, opts ...bucketConfigurationOpts)
|
|||
})
|
||||
}
|
||||
|
||||
err := bucket.Version.Initialize()
|
||||
err = bucket.Version.Initialize()
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Version initialization failed",
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ require (
|
|||
|
||||
require (
|
||||
cloud.google.com/go v0.110.8 // indirect
|
||||
cloud.google.com/go/compute v1.23.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.3 // indirect
|
||||
cloud.google.com/go/storage v1.35.1 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
|
||||
|
|
@ -75,14 +74,14 @@ require (
|
|||
github.com/pkg/sftp v1.13.2 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/ulikunitz/xz v0.5.14 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/oauth2 v0.13.0 // indirect
|
||||
golang.org/x/oauth2 v0.27.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/term v0.30.0 // indirect
|
||||
|
|
@ -90,7 +89,6 @@ require (
|
|||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.150.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME=
|
||||
cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk=
|
||||
cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0=
|
||||
cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/iam v1.1.3 h1:18tKG7DzydKWUnLjonWcJO6wjSCAtzh4GcRKlH/Hrzc=
|
||||
cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE=
|
||||
cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w=
|
||||
|
|
@ -329,8 +327,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri
|
|||
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg=
|
||||
github.com/ulikunitz/xz v0.5.14/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
|
|
@ -362,7 +360,6 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
|
@ -374,8 +371,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
|||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
|
||||
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
@ -447,8 +444,6 @@ google.golang.org/api v0.150.0 h1:Z9k22qD289SZ8gCJrk4DrWXkNjtfvKAUo/l1ma8eBYE=
|
|||
google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ const wrapPowershellString string = `
|
|||
if ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) {
|
||||
$exitCode = $LASTEXITCODE
|
||||
}
|
||||
|
||||
Write-Host $result
|
||||
exit $exitCode
|
||||
|
||||
`
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ func TestProvisionerPrepare_extractScript(t *testing.T) {
|
|||
|
||||
// File contents should contain 2 lines concatenated by newlines: foo\nbar
|
||||
readFile, err := os.ReadFile(file)
|
||||
expectedContents := " \n\tif (Test-Path variable:global:ProgressPreference) {\n\t set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'\n\t}\n\t\n\t$exitCode = 0\n\ttry {\n\t$env:PACKER_BUILDER_TYPE=\"\"; $env:PACKER_BUILD_NAME=\"\"; \n\tfoo\n\tbar\n\t\n\t$exitCode = 0\n\t} catch {\n\tWrite-Error \"An error occurred: $_\"\n\t$exitCode = 1\n\t}\n\t\n\tif ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) {\n\t\t$exitCode = $LASTEXITCODE\n\t}\n\t\n\tWrite-Host $result\n\texit $exitCode\n\n"
|
||||
expectedContents := "if (Test-Path variable:global:ProgressPreference) {\n set-variable -name variable:global:ProgressPreference -value 'SilentlyContinue'\n }\n \n $exitCode = 0\n try {\n $env:PACKER_BUILDER_TYPE=\"\"; $env:PACKER_BUILD_NAME=\"\"; \n foo\n bar\n \n $exitCode = 0\n } catch {\n Write-Error \"An error occurred: $_\"\n $exitCode = 1\n }\n \n if ($LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0) {\n $exitCode = $LASTEXITCODE\n }\n exit $exitCode"
|
||||
normalizedExpectedContent := normalizeWhiteSpace(expectedContents)
|
||||
if err != nil {
|
||||
t.Fatalf("Should not be error: %s", err)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.14.1
|
||||
1.14.2
|
||||
|
|
@ -1 +1 @@
|
|||
v18
|
||||
v22
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM docker.mirror.hashicorp.services/node:18.18.2-alpine
|
||||
FROM docker.mirror.hashicorp.services/node:22.17.1-alpine
|
||||
RUN apk add --update --no-cache git make g++ automake autoconf libtool nasm libpng-dev
|
||||
|
||||
COPY ./package.json /website/package.json
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ The Docker image is pre-built with all the website dependencies installed, which
|
|||
|
||||
### With Node
|
||||
|
||||
If your local development environment has a supported version (v18+) of [node installed](https://nodejs.org/en/) you can run:
|
||||
If your local development environment has a supported version (v22+) of [node installed](https://nodejs.org/en/) you can run:
|
||||
|
||||
- `npm install`
|
||||
- `npm start`
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ page_title: packer build - Commands
|
|||
|
||||
# `packer build` command reference
|
||||
|
||||
<Note>
|
||||
|
||||
Starting August 1st, 2025, the source for many official HashiCorp-maintained Packer plugins is moving from GitHub releases to the official HashiCorp release site, [releases.hashicorp.com](https://releases.hashicorp.com). Refer to [Install HashiCorp-maintained plugins](/packer/docs/plugins/install#install-hashicorp-maintained-plugins) for more information.
|
||||
|
||||
</Note>
|
||||
|
||||
The `packer build` command takes a template and runs all the builds within it
|
||||
in order to generate a set of artifacts. The various builds specified within a
|
||||
template are executed in parallel, unless otherwise specified. And the
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ page_title: packer init command reference
|
|||
|
||||
# `packer init` command reference
|
||||
|
||||
<Note>
|
||||
|
||||
Starting August 1st, 2025, the source for many official HashiCorp-maintained Packer plugins is moving from GitHub releases to the official HashiCorp release site, [releases.hashicorp.com](https://releases.hashicorp.com). Refer to [Install HashiCorp-maintained plugins](/packer/docs/plugins/install#install-hashicorp-maintained-plugins) for more information.
|
||||
|
||||
</Note>
|
||||
|
||||
|
||||
The `packer init` command initializes Packer according to an HCL template configuration. Refer to [Installing Plugins](/packer/docs/plugins/install) for additional information about installing plugins.
|
||||
|
||||
## Description
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ page_title: packer plugins install command reference
|
|||
|
||||
# `packer plugins install` command reference
|
||||
|
||||
<Note>
|
||||
|
||||
Starting August 1st, 2025, the source for many official HashiCorp-maintained Packer plugins is moving from GitHub releases to the official HashiCorp release site, [releases.hashicorp.com](https://releases.hashicorp.com). Refer to [Install HashiCorp-maintained plugins](/packer/docs/plugins/install#install-hashicorp-maintained-plugins) for more information.
|
||||
|
||||
</Note>
|
||||
|
||||
The `packer plugins install` command downloads and installs the most recent version of a plugin binary. Refer to [Installing Plugins](/packer/docs/plugins/install) for additional information about installing plugins.
|
||||
|
||||
## Description
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ configurations.
|
|||
You can use HCP Packer with both JSON and HCL2 templates. If you are using JSON templates, we recommend getting started with
|
||||
the [HCP Packer environment variables](#hcp-packer-environment-variables) and then migrating to HCL when possible.
|
||||
|
||||
## Requirements
|
||||
## Requirements
|
||||
|
||||
Packer version 1.9.1 or newer is required to use the `HCP_PROJECT_ID` environment variable, which lets Packer connect to specific projects in HCP. Your builds will fail if you configure them to send mulit-project metadata using Packer versions older than 1.9.1.
|
||||
|
||||
|
|
@ -35,7 +35,9 @@ changing your template. You can use environment variables with both JSON and HCL
|
|||
Refer to [Basic Configuration With Environment Variables](/hcp/docs/packer/store-image-metadata/packer-template-configuration#basic-configuration-with-environment-variables)
|
||||
in the HCP Packer documentation for complete instructions and examples.
|
||||
|
||||
You must set the following environment variables to enable Packer to push metadata to a registry.
|
||||
You must set authentication environment variables to connect to HCP Packer, you can either directly set a client ID and secret, or (on Packer versions 1.14.2 and later) use an HCP certificate file
|
||||
|
||||
For client ID and secret, you set the following environemnt variables
|
||||
|
||||
- `HCP_CLIENT_ID` - The HCP client ID of a HashiCorp Cloud Platform service principle that Packer can use to
|
||||
authenticate to an HCP Packer Registry.
|
||||
|
|
@ -43,6 +45,10 @@ authenticate to an HCP Packer Registry.
|
|||
- `HCP_CLIENT_SECRET` - The HCP client secret of the HashiCorp Cloud Platform service principle that Packer
|
||||
can use to authenticate to an HCP Packer Registry.
|
||||
|
||||
For certificate based auth simply specify the location of the valid HCP certificate file in the `HCP_CRED_FILE` environment variable, or place it in the default location for the HCP SDK, `~/.config/hcp/cred_file.json`
|
||||
|
||||
See the following HCP docs for more information on [Workload Identity Federation](https://developer.hashicorp.com/hcp/docs/hcp/iam/service-principal/workload-identity-federation) and certificate authentication
|
||||
|
||||
- `HCP_PACKER_BUCKET_NAME` - The name of the HCP Packer Bucket where you want HCP Packer to store artifact metadata
|
||||
from builds associated with your template. HCP Packer automatically creates the bucket if it does not already exist.
|
||||
If your HCL2 template contains an `hcp_packer_registry` block, the bucket name specified in the configuration will be
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ page_title: Plugins
|
|||
|
||||
# Plugin installation overview
|
||||
|
||||
<Note>
|
||||
|
||||
Starting August 1st, 2025, the source for many official HashiCorp-maintained Packer plugins is moving from GitHub releases to the official HashiCorp release site, [releases.hashicorp.com](https://releases.hashicorp.com). Refer to [Install HashiCorp-maintained plugins](/packer/docs/plugins/install#install-hashicorp-maintained-plugins) for more information.
|
||||
|
||||
</Note>
|
||||
|
||||
This topic provides overview information about installing and loading Packer plugins. Plugins are standalone applications that perform additional tasks during each build.
|
||||
|
||||
## Introduction
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ page_title: Install Plugins
|
|||
|
||||
# Install Plugins
|
||||
|
||||
<Note>
|
||||
|
||||
Starting August 1st, 2025, the source for many official HashiCorp-maintained Packer plugins is moving from GitHub releases to the official HashiCorp release site, [releases.hashicorp.com](https://releases.hashicorp.com). Refer to [Install HashiCorp-maintained plugins](#install-hashicorp-maintained-plugins) for more information.
|
||||
|
||||
</Note>
|
||||
|
||||
This topic describes how to install external plugins for Packer. Refer to [Packer Plugins Overview](/packer/docs/plugins) for additional information about plugins.
|
||||
|
||||
## Overview
|
||||
|
|
@ -29,9 +35,13 @@ Note that Packer checks the plugin installation directory against the `required_
|
|||
|
||||
By default, Packer installs plugins into the plugins directory at `$HOME/.config/packer/plugins` on Unix and `%APPDATA%\packer.d\plugins` on Windows, but you can specify a different directory using the `PACKER_PLUGIN_PATH` environment variable.
|
||||
|
||||
~> Note: Plugin installation requires access to temporary files under `TMPDIR`. If the system's temp directory is non-writable or non-executable, use TMPDIR to override the location of the temporary file store used by Packer.
|
||||
<Note>
|
||||
|
||||
Plugin installation requires access to temporary files under `TMPDIR`. If the system's temp directory is non-writable or non-executable, use TMPDIR to override the location of the temporary file store used by Packer.
|
||||
Refer to the [Packer configuration reference](/packer/docs/configure) for additional information.
|
||||
|
||||
</Note>
|
||||
|
||||
## Requirements
|
||||
|
||||
To install a plugin from a remote source, the plugin must meet the following requirements:
|
||||
|
|
@ -69,11 +79,22 @@ pinning plugin versions for build reproducibility. Refer to the [`packer` block
|
|||
|
||||
1. Run the `packer init` command. Packer lists all installed plugins then installs the latest plugin version matching the version constraints specified in the `required_plugins` block. Refer to the [`init` command reference](/packer/docs/commands/init) for additional information.
|
||||
|
||||
~> Note: With the new Packer release starting from version 1.14.0, the packer init command will automatically install official (Amazon, Ansible, Azure, Docker, GoogleCloudPlatform, Qemu, Vagrant, VirtualBox) plugins from the [HashiCorp release site](https://releases.hashicorp.com/).
|
||||
These official plugins will now be released through the official release site only.
|
||||
## Install HashiCorp-maintained plugins
|
||||
|
||||
Going forward, to use newer versions of official Packer plugins, you'll need to upgrade to Packer version 1.14.0 or later. If you're using an older version, you can still install plugins, but as a workaround, you'll need to [manually install them using the CLI](https://developer.hashicorp.com/packer/docs/plugins/install#manually-install-plugins-using-the-cli).
|
||||
There is no change to the syntax or commands for installing plugins.
|
||||
HashiCorp now makes the following official HashiCorp-maintained plugins available through the [HashiCorp release site](https://releases.hashicorp.com/).
|
||||
|
||||
These plugins include:
|
||||
|
||||
- [Amazon](https://developer.hashicorp.com/packer/integrations/hashicorp/amazon)
|
||||
- [Ansible](https://developer.hashicorp.com/packer/integrations/hashicorp/ansible)
|
||||
- [Azure](https://developer.hashicorp.com/packer/integrations/hashicorp/azure)
|
||||
- [Docker](https://developer.hashicorp.com/packer/integrations/hashicorp/docker)
|
||||
- [Google Cloud Platform](https://developer.hashicorp.com/packer/integrations/hashicorp/googlecompute)
|
||||
- [QEMU](https://developer.hashicorp.com/packer/integrations/hashicorp/qemu)
|
||||
- [Vagrant](https://developer.hashicorp.com/packer/integrations/hashicorp/vagrant)
|
||||
- [VirtualBox](https://developer.hashicorp.com/packer/integrations/hashicorp/virtualbox)
|
||||
|
||||
Starting in Packer 1.14.0, Packer automatically installs these plugins from the new release source, and you do not need to make any changes to your Packer templates. To continue to automatically receive updates to these plugins, you must upgrade to Packer 1.14.0 or newer. If you cannot upgrade your version of Packer, you can still install new versions of these plugins manually. Refer to [Manually install plugins using the CLI](#manually-install-plugins-using-the-cli) for more information.
|
||||
|
||||
## Manually install plugins using the CLI
|
||||
|
||||
|
|
@ -95,7 +116,6 @@ $ packer plugins install --path happycloud github.com/hashicorp/happycloud
|
|||
|
||||
Refer to the [`packer plugins install`](/packer/docs/commands/plugins/install) reference for additional information.
|
||||
|
||||
|
||||
## Upgrade plugins
|
||||
|
||||
To upgrade plugins that are already installed, run the `packer init` with the `--upgrade` flag. Packer retrieves the latest versions of installed plugins specified in the template configuration.
|
||||
|
|
@ -110,7 +130,6 @@ Refer to [`packer init` command](/packer/docs/commands/init) for additional info
|
|||
|
||||
## Use a plugin under development
|
||||
|
||||
|
||||
If a development binary, such as a manually-built binary, is available at the specified source, Packer uses it in the build if it is the highest compatible version installed and if no final plugin version with the same version number is installed alongside it.
|
||||
|
||||
In the following example, version `1.1.0` or newer is required:
|
||||
|
|
@ -155,7 +174,6 @@ When a non-development version of 1.1.1 becomes available, the binary takes prec
|
|||
└── packer-plugin-amazon_v1.1.1_x5.0_darwin_arm64_SHA256SUM
|
||||
```
|
||||
|
||||
|
||||
### Example Docker plugin
|
||||
|
||||
Complete the following steps to build and install a custom version of the Docker plugin as an example:
|
||||
|
|
|
|||
Loading…
Reference in a new issue