move proxy behind feature flag
This commit is contained in:
parent
1963f3aa6f
commit
ca5814ab74
|
@ -63,6 +63,7 @@ func PopulateProvisionHookData(state multistep.StateBag) map[string]interface{}
|
|||
hookData["ConnType"] = commConf.Type
|
||||
hookData["SSHPublicKey"] = string(commConf.SSHPublicKey)
|
||||
hookData["SSHPrivateKey"] = string(commConf.SSHPrivateKey)
|
||||
hookData["SSHPrivateKeyFile"] = commConf.SSHPrivateKeyFile
|
||||
|
||||
// Backwards compatibility; in practice, WinRMPassword is fulfilled by
|
||||
// Password.
|
||||
|
|
|
@ -67,6 +67,9 @@ type Config struct {
|
|||
GalaxyCommand string `mapstructure:"galaxy_command"`
|
||||
GalaxyForceInstall bool `mapstructure:"galaxy_force_install"`
|
||||
RolesPath string `mapstructure:"roles_path"`
|
||||
//TODO: change default to false in v1.6.0.
|
||||
UseProxy config.Trilean `mapstructure:"use_proxy"`
|
||||
userWasEmpty bool
|
||||
}
|
||||
|
||||
type Provisioner struct {
|
||||
|
@ -76,6 +79,9 @@ type Provisioner struct {
|
|||
ansibleVersion string
|
||||
ansibleMajVersion uint
|
||||
generatedData map[string]interface{}
|
||||
|
||||
setupAdapterFunc func(ui packer.Ui, comm packer.Communicator) (string, error)
|
||||
executeAnsibleFunc func(ui packer.Ui, comm packer.Communicator, privKeyFile string) error
|
||||
}
|
||||
|
||||
func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { return p.config.FlatMapstructure().HCL2Spec() }
|
||||
|
@ -163,6 +169,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
}
|
||||
|
||||
if p.config.User == "" {
|
||||
p.config.userWasEmpty = true
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
|
@ -174,6 +181,16 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("user: could not determine current user from environment."))
|
||||
}
|
||||
|
||||
// These fields exist so that we can replace the functions for testing
|
||||
// logic inside of the Provision func; in actual use, these don't ever
|
||||
// need to get set.
|
||||
if p.setupAdapterFunc == nil {
|
||||
p.setupAdapterFunc = p.setupAdapter
|
||||
}
|
||||
if p.executeAnsibleFunc == nil {
|
||||
p.executeAnsibleFunc = p.executeAnsible
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
@ -207,40 +224,17 @@ func (p *Provisioner) getVersion() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, generatedData map[string]interface{}) error {
|
||||
ui.Say("Provisioning with Ansible...")
|
||||
// Interpolate env vars to check for generated values like password and port
|
||||
p.generatedData = generatedData
|
||||
p.config.ctx.Data = generatedData
|
||||
for i, envVar := range p.config.AnsibleEnvVars {
|
||||
envVar, err := interpolate.Render(envVar, &p.config.ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not interpolate ansible env vars: %s", err)
|
||||
}
|
||||
p.config.AnsibleEnvVars[i] = envVar
|
||||
}
|
||||
// Interpolate extra vars to check for generated values like password and port
|
||||
for i, arg := range p.config.ExtraArguments {
|
||||
arg, err := interpolate.Render(arg, &p.config.ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not interpolate ansible env vars: %s", err)
|
||||
}
|
||||
p.config.ExtraArguments[i] = arg
|
||||
}
|
||||
func (p *Provisioner) setupAdapter(ui packer.Ui, comm packer.Communicator) (string, error) {
|
||||
ui.Message("Setting up proxy adapter for Ansible....")
|
||||
|
||||
k, err := newUserKey(p.config.SSHAuthorizedKeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
|
||||
hostSigner, err := newSigner(p.config.SSHHostKeyFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating host signer: %s", err)
|
||||
}
|
||||
|
||||
// Remove the private key file
|
||||
if len(k.privKeyFile) > 0 {
|
||||
defer os.Remove(k.privKeyFile)
|
||||
return "", fmt.Errorf("error creating host signer: %s", err)
|
||||
}
|
||||
|
||||
keyChecker := ssh.CertChecker{
|
||||
|
@ -298,7 +292,7 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
|
|||
}()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
|
||||
ui = &packer.SafeUi{
|
||||
|
@ -307,50 +301,155 @@ func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.C
|
|||
}
|
||||
p.adapter = adapter.NewAdapter(p.done, localListener, config, p.config.SFTPCmd, ui, comm)
|
||||
|
||||
defer func() {
|
||||
log.Print("shutting down the SSH proxy")
|
||||
close(p.done)
|
||||
p.adapter.Shutdown()
|
||||
}()
|
||||
return k.privKeyFile, nil
|
||||
}
|
||||
|
||||
go p.adapter.Serve()
|
||||
func (p *Provisioner) createInventoryFile(hostIP string, hostPort int) error {
|
||||
log.Printf("Creating inventory file for Ansible run...")
|
||||
tf, err := ioutil.TempFile(p.config.InventoryDirectory, "packer-provisioner-ansible")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error preparing inventory file: %s", err)
|
||||
}
|
||||
host := fmt.Sprintf("%s ansible_host=%s ansible_user=%s ansible_port=%d\n",
|
||||
p.config.HostAlias, hostIP, p.config.User, hostPort)
|
||||
if p.ansibleMajVersion < 2 {
|
||||
host = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_user=%s ansible_ssh_port=%d\n",
|
||||
p.config.HostAlias, hostIP, p.config.User, hostPort)
|
||||
}
|
||||
|
||||
w := bufio.NewWriter(tf)
|
||||
w.WriteString(host)
|
||||
|
||||
for _, group := range p.config.Groups {
|
||||
fmt.Fprintf(w, "[%s]\n%s", group, host)
|
||||
}
|
||||
|
||||
for _, group := range p.config.EmptyGroups {
|
||||
fmt.Fprintf(w, "[%s]\n", group)
|
||||
}
|
||||
|
||||
if err := w.Flush(); err != nil {
|
||||
tf.Close()
|
||||
os.Remove(tf.Name())
|
||||
return fmt.Errorf("Error preparing inventory file: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
p.config.InventoryFile = tf.Name()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, generatedData map[string]interface{}) error {
|
||||
ui.Say("Provisioning with Ansible...")
|
||||
// Interpolate env vars to check for generated values like password and port
|
||||
p.generatedData = generatedData
|
||||
p.config.ctx.Data = generatedData
|
||||
for i, envVar := range p.config.AnsibleEnvVars {
|
||||
envVar, err := interpolate.Render(envVar, &p.config.ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not interpolate ansible env vars: %s", err)
|
||||
}
|
||||
p.config.AnsibleEnvVars[i] = envVar
|
||||
}
|
||||
// Interpolate extra vars to check for generated values like password and port
|
||||
for i, arg := range p.config.ExtraArguments {
|
||||
arg, err := interpolate.Render(arg, &p.config.ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not interpolate ansible env vars: %s", err)
|
||||
}
|
||||
p.config.ExtraArguments[i] = arg
|
||||
}
|
||||
|
||||
// Set up proxy if there's no host IP to access, regardless of user config.
|
||||
hostIP := generatedData["Host"].(string)
|
||||
|
||||
if hostIP == "" && p.config.UseProxy.False() {
|
||||
ui.Error("Warning: use_proxy is false, but instance does" +
|
||||
" not have an IP address to give to Ansible. Falling back" +
|
||||
" to use localhost proxy.")
|
||||
p.config.UseProxy = config.TriTrue
|
||||
}
|
||||
|
||||
privKeyFile := ""
|
||||
if !p.config.UseProxy.False() {
|
||||
// We set up the proxy if useProxy is either true or unset.
|
||||
pkf, err := p.setupAdapterFunc(ui, comm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// This is necessary to avoid accidentally redeclaring
|
||||
// privKeyFile in the scope of this if statement.
|
||||
privKeyFile = pkf
|
||||
|
||||
defer func() {
|
||||
log.Print("shutting down the SSH proxy")
|
||||
close(p.done)
|
||||
p.adapter.Shutdown()
|
||||
}()
|
||||
|
||||
go p.adapter.Serve()
|
||||
|
||||
// Remove the private key file
|
||||
if len(privKeyFile) > 0 {
|
||||
defer os.Remove(privKeyFile)
|
||||
}
|
||||
} else {
|
||||
ui.Message("Not using Proxy adapter for Ansible run:\n" +
|
||||
"\tUsing ssh keys from Packer communicator...")
|
||||
// In this situation, we need to make sure we have the
|
||||
// private key we actually use to access the instance.
|
||||
SSHPrivateKeyFile := generatedData["SSHPrivateKeyFile"].(string)
|
||||
if SSHPrivateKeyFile != "" {
|
||||
privKeyFile = SSHPrivateKeyFile
|
||||
} else {
|
||||
// See if we can get a private key and write that to a tmpfile
|
||||
SSHPrivateKey := generatedData["SSHPrivateKey"].([]byte)
|
||||
tmpSSHPrivateKey, err := tmp.File("ansible-key")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing private key to temp file for"+
|
||||
"ansible connection: %v", err)
|
||||
}
|
||||
_, err = tmpSSHPrivateKey.Write(SSHPrivateKey)
|
||||
if err != nil {
|
||||
return errors.New("failed to write private key to temp file")
|
||||
}
|
||||
err = tmpSSHPrivateKey.Close()
|
||||
if err != nil {
|
||||
return errors.New("failed to close private key temp file")
|
||||
}
|
||||
privKeyFile = tmpSSHPrivateKey.Name()
|
||||
}
|
||||
|
||||
// Also make sure that the username matches the SSH keys given.
|
||||
if p.config.userWasEmpty {
|
||||
p.config.User = generatedData["User"].(string)
|
||||
}
|
||||
}
|
||||
|
||||
if len(p.config.InventoryFile) == 0 {
|
||||
tf, err := ioutil.TempFile(p.config.InventoryDirectory, "packer-provisioner-ansible")
|
||||
hostIP = "127.0.0.1"
|
||||
hostPort := p.config.LocalPort
|
||||
if p.config.UseProxy.False() {
|
||||
// We aren't using a proxy, so we need to retrieve the
|
||||
// host IP and port from generated data.
|
||||
hostIP = generatedData["Host"].(string)
|
||||
hostPort = int(generatedData["Port"].(int64))
|
||||
}
|
||||
|
||||
// Create the inventory file
|
||||
err := p.createInventoryFile(hostIP, hostPort)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error preparing inventory file: %s", err)
|
||||
}
|
||||
defer os.Remove(tf.Name())
|
||||
|
||||
host := fmt.Sprintf("%s ansible_host=127.0.0.1 ansible_user=%s ansible_port=%d\n",
|
||||
p.config.HostAlias, p.config.User, p.config.LocalPort)
|
||||
if p.ansibleMajVersion < 2 {
|
||||
host = fmt.Sprintf("%s ansible_ssh_host=127.0.0.1 ansible_ssh_user=%s ansible_ssh_port=%d\n",
|
||||
p.config.HostAlias, p.config.User, p.config.LocalPort)
|
||||
return err
|
||||
}
|
||||
|
||||
w := bufio.NewWriter(tf)
|
||||
w.WriteString(host)
|
||||
for _, group := range p.config.Groups {
|
||||
fmt.Fprintf(w, "[%s]\n%s", group, host)
|
||||
}
|
||||
|
||||
for _, group := range p.config.EmptyGroups {
|
||||
fmt.Fprintf(w, "[%s]\n", group)
|
||||
}
|
||||
|
||||
if err := w.Flush(); err != nil {
|
||||
tf.Close()
|
||||
return fmt.Errorf("Error preparing inventory file: %s", err)
|
||||
}
|
||||
tf.Close()
|
||||
p.config.InventoryFile = tf.Name()
|
||||
// Delete the generated inventory file
|
||||
defer func() {
|
||||
os.Remove(p.config.InventoryFile)
|
||||
p.config.InventoryFile = ""
|
||||
}()
|
||||
}
|
||||
|
||||
if err := p.executeAnsible(ui, comm, k.privKeyFile); err != nil {
|
||||
if err := p.executeAnsibleFunc(ui, comm, privKeyFile); err != nil {
|
||||
return fmt.Errorf("Error executing Ansible: %s", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ type FlatConfig struct {
|
|||
GalaxyCommand *string `mapstructure:"galaxy_command" cty:"galaxy_command"`
|
||||
GalaxyForceInstall *bool `mapstructure:"galaxy_force_install" cty:"galaxy_force_install"`
|
||||
RolesPath *string `mapstructure:"roles_path" cty:"roles_path"`
|
||||
UseProxy *bool `mapstructure:"use_proxy" cty:"use_proxy"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
|
@ -77,6 +78,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"galaxy_command": &hcldec.AttrSpec{Name: "galaxy_command", Type: cty.String, Required: false},
|
||||
"galaxy_force_install": &hcldec.AttrSpec{Name: "galaxy_force_install", Type: cty.Bool, Required: false},
|
||||
"roles_path": &hcldec.AttrSpec{Name: "roles_path", Type: cty.String, Required: false},
|
||||
"use_proxy": &hcldec.AttrSpec{Name: "use_proxy", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -14,9 +14,32 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
confighelper "github.com/hashicorp/packer/helper/config"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type provisionLogicTracker struct {
|
||||
setupAdapterCalled bool
|
||||
executeAnsibleCalled bool
|
||||
happyPath bool
|
||||
}
|
||||
|
||||
func (l *provisionLogicTracker) setupAdapter(ui packer.Ui, comm packer.Communicator) (string, error) {
|
||||
l.setupAdapterCalled = true
|
||||
if l.happyPath {
|
||||
return "fakeKeyString", nil
|
||||
}
|
||||
return "", fmt.Errorf("chose sadpath")
|
||||
}
|
||||
|
||||
func (l *provisionLogicTracker) executeAnsible(ui packer.Ui, comm packer.Communicator, privKeyFile string) error {
|
||||
l.executeAnsibleCalled = true
|
||||
if l.happyPath {
|
||||
return fmt.Errorf("Chose sadpath")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Be sure to remove the Ansible stub file in each test with:
|
||||
// defer os.Remove(config["command"].(string))
|
||||
func testConfig(t *testing.T) map[string]interface{} {
|
||||
|
@ -354,3 +377,220 @@ func TestAnsibleLongMessages(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateInventoryFile_vers1(t *testing.T) {
|
||||
var p Provisioner
|
||||
p.Prepare(testConfig(t))
|
||||
defer os.Remove(p.config.Command)
|
||||
p.ansibleMajVersion = 1
|
||||
p.config.User = "testuser"
|
||||
|
||||
err := p.createInventoryFile("123.45.67.89", 2222)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating config using localhost and local port proxy")
|
||||
}
|
||||
if p.config.InventoryFile == "" {
|
||||
t.Fatalf("No inventory file was created")
|
||||
}
|
||||
defer os.Remove(p.config.InventoryFile)
|
||||
f, err := ioutil.ReadFile(p.config.InventoryFile)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't read created inventoryfile: %s", err)
|
||||
}
|
||||
|
||||
expected := "default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=2222\n"
|
||||
if fmt.Sprintf("%s", f) != expected {
|
||||
t.Fatalf("File didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", expected, f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateInventoryFile_vers2(t *testing.T) {
|
||||
var p Provisioner
|
||||
p.Prepare(testConfig(t))
|
||||
defer os.Remove(p.config.Command)
|
||||
p.ansibleMajVersion = 2
|
||||
p.config.User = "testuser"
|
||||
|
||||
err := p.createInventoryFile("123.45.67.89", 1234)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating config using localhost and local port proxy")
|
||||
}
|
||||
if p.config.InventoryFile == "" {
|
||||
t.Fatalf("No inventory file was created")
|
||||
}
|
||||
defer os.Remove(p.config.InventoryFile)
|
||||
f, err := ioutil.ReadFile(p.config.InventoryFile)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't read created inventoryfile: %s", err)
|
||||
}
|
||||
expected := "default ansible_host=123.45.67.89 ansible_user=testuser ansible_port=1234\n"
|
||||
if fmt.Sprintf("%s", f) != expected {
|
||||
t.Fatalf("File didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", expected, f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateInventoryFile_Groups(t *testing.T) {
|
||||
var p Provisioner
|
||||
p.Prepare(testConfig(t))
|
||||
defer os.Remove(p.config.Command)
|
||||
p.ansibleMajVersion = 1
|
||||
p.config.User = "testuser"
|
||||
p.config.Groups = []string{"Group1", "Group2"}
|
||||
|
||||
err := p.createInventoryFile("123.45.67.89", 1234)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating config using localhost and local port proxy")
|
||||
}
|
||||
if p.config.InventoryFile == "" {
|
||||
t.Fatalf("No inventory file was created")
|
||||
}
|
||||
defer os.Remove(p.config.InventoryFile)
|
||||
f, err := ioutil.ReadFile(p.config.InventoryFile)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't read created inventoryfile: %s", err)
|
||||
}
|
||||
expected := `default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
[Group1]
|
||||
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
[Group2]
|
||||
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
`
|
||||
if fmt.Sprintf("%s", f) != expected {
|
||||
t.Fatalf("File didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", expected, f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateInventoryFile_EmptyGroups(t *testing.T) {
|
||||
var p Provisioner
|
||||
p.Prepare(testConfig(t))
|
||||
defer os.Remove(p.config.Command)
|
||||
p.ansibleMajVersion = 1
|
||||
p.config.User = "testuser"
|
||||
p.config.EmptyGroups = []string{"Group1", "Group2"}
|
||||
|
||||
err := p.createInventoryFile("123.45.67.89", 1234)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating config using localhost and local port proxy")
|
||||
}
|
||||
if p.config.InventoryFile == "" {
|
||||
t.Fatalf("No inventory file was created")
|
||||
}
|
||||
defer os.Remove(p.config.InventoryFile)
|
||||
f, err := ioutil.ReadFile(p.config.InventoryFile)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't read created inventoryfile: %s", err)
|
||||
}
|
||||
expected := `default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
[Group1]
|
||||
[Group2]
|
||||
`
|
||||
if fmt.Sprintf("%s", f) != expected {
|
||||
t.Fatalf("File didn't match expected:\n\n expected: \n%s\n; recieved: \n%s\n", expected, f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateInventoryFile_GroupsAndEmptyGroups(t *testing.T) {
|
||||
var p Provisioner
|
||||
p.Prepare(testConfig(t))
|
||||
defer os.Remove(p.config.Command)
|
||||
p.ansibleMajVersion = 1
|
||||
p.config.User = "testuser"
|
||||
p.config.Groups = []string{"Group1", "Group2"}
|
||||
p.config.EmptyGroups = []string{"Group3"}
|
||||
|
||||
err := p.createInventoryFile("123.45.67.89", 1234)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating config using localhost and local port proxy")
|
||||
}
|
||||
if p.config.InventoryFile == "" {
|
||||
t.Fatalf("No inventory file was created")
|
||||
}
|
||||
defer os.Remove(p.config.InventoryFile)
|
||||
f, err := ioutil.ReadFile(p.config.InventoryFile)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't read created inventoryfile: %s", err)
|
||||
}
|
||||
expected := `default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
[Group1]
|
||||
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
[Group2]
|
||||
default ansible_ssh_host=123.45.67.89 ansible_ssh_user=testuser ansible_ssh_port=1234
|
||||
[Group3]
|
||||
`
|
||||
if fmt.Sprintf("%s", f) != expected {
|
||||
t.Fatalf("File didn't match expected:\n\n file is \n\n %s", f)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUseProxy(t *testing.T) {
|
||||
type testcase struct {
|
||||
UseProxy confighelper.Trilean
|
||||
generatedData map[string]interface{}
|
||||
expectedSetupAdapterCalled bool
|
||||
explanation string
|
||||
}
|
||||
|
||||
tcs := []testcase{
|
||||
{
|
||||
explanation: "use_proxy is true; we should set up adapter",
|
||||
UseProxy: confighelper.TriTrue,
|
||||
generatedData: map[string]interface{}{
|
||||
"Host": "123.45.67.8",
|
||||
"Port": int64(1234),
|
||||
},
|
||||
expectedSetupAdapterCalled: true,
|
||||
},
|
||||
{
|
||||
explanation: "use_proxy is false but no IP addr is available; we should set up adapter anyway.",
|
||||
UseProxy: confighelper.TriFalse,
|
||||
generatedData: map[string]interface{}{
|
||||
"Host": "",
|
||||
"Port": nil,
|
||||
},
|
||||
expectedSetupAdapterCalled: true,
|
||||
},
|
||||
{
|
||||
explanation: "use_proxy is false; we shouldn't set up adapter.",
|
||||
UseProxy: confighelper.TriFalse,
|
||||
generatedData: map[string]interface{}{
|
||||
"Host": "123.45.67.8",
|
||||
"Port": int64(1234),
|
||||
},
|
||||
expectedSetupAdapterCalled: false,
|
||||
},
|
||||
{
|
||||
explanation: "use_proxy is unset; we should default to setting up the adapter (for now).",
|
||||
UseProxy: confighelper.TriUnset,
|
||||
generatedData: map[string]interface{}{
|
||||
"Host": "123.45.67.8",
|
||||
"Port": int64(1234),
|
||||
},
|
||||
expectedSetupAdapterCalled: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
var p Provisioner
|
||||
p.Prepare(testConfig(t))
|
||||
p.config.UseProxy = tc.UseProxy
|
||||
defer os.Remove(p.config.Command)
|
||||
p.ansibleMajVersion = 1
|
||||
|
||||
var l provisionLogicTracker
|
||||
l.setupAdapterCalled = false
|
||||
p.setupAdapterFunc = l.setupAdapter
|
||||
p.executeAnsibleFunc = l.executeAnsible
|
||||
ctx := context.TODO()
|
||||
comm := new(packer.MockCommunicator)
|
||||
ui := &packer.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
}
|
||||
p.Provision(ctx, ui, comm, tc.generatedData)
|
||||
|
||||
if l.setupAdapterCalled != tc.expectedSetupAdapterCalled {
|
||||
t.Fatalf("Should have called set up adapter: %s", tc.explanation)
|
||||
}
|
||||
os.Remove(p.config.Command)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,6 +183,22 @@ Optional Parameters:
|
|||
- `user` (string) - The `ansible_user` to use. Defaults to the user running
|
||||
packer.
|
||||
|
||||
- `use_proxy` (boolean) - Whether or not to set up a localhost proxy adapter
|
||||
so that Ansible has an IP address to connect to, even if your guest does not
|
||||
have an IP address. For example, the adapter is necessary for Docker builds
|
||||
to use the Ansible provisioner. Defaults to "true". If you set this option
|
||||
to `false`, but Packer cannot find an IP address to connect Ansible to, it
|
||||
will automatically set up the adapter anyway.
|
||||
|
||||
In order for Ansible to connect properly even when use_proxy is false, you
|
||||
need to make sure that you are either providing a valid username and ssh key
|
||||
to the ansible provisioner directly, or that the username and ssh key
|
||||
being used by the ssh communicator will work for your needs. If you do not
|
||||
provide a user to ansible, it will use the user associated with your
|
||||
builder, not the user running Packer.
|
||||
|
||||
use_proxy=false is currently only supported for SSH, not winRM.
|
||||
|
||||
<%= partial "partials/provisioners/common-config" %>
|
||||
|
||||
## Default Extra Variables
|
||||
|
|
Loading…
Reference in New Issue