Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions provisioner/ansible/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net"
"strings"

"github.com/google/shlex"
"github.com/mitchellh/packer/packer"
"golang.org/x/crypto/ssh"
)
Expand Down Expand Up @@ -189,7 +190,7 @@ func (c *adapter) exec(command string, in io.Reader, out io.Writer, err io.Write
var exitStatus int
switch {
case strings.HasPrefix(command, "scp ") && serveSCP(command[4:]):
err := c.scpExec(command[4:], in, out, err)
err := c.scpExec(command[4:], in, out)
if err != nil {
log.Println(err)
exitStatus = 1
Expand All @@ -205,9 +206,16 @@ func serveSCP(args string) bool {
return bytes.IndexAny(opts, "tf") >= 0
}

func (c *adapter) scpExec(args string, in io.Reader, out io.Writer, err io.Writer) error {
func (c *adapter) scpExec(args string, in io.Reader, out io.Writer) error {
opts, rest := scpOptions(args)

// remove the quoting that ansible added to rest for shell safety.
shargs, err := shlex.Split(rest)
if err != nil {
return err
}
rest = strings.Join(shargs, "")

if i := bytes.IndexByte(opts, 't'); i >= 0 {
return scpUploadSession(opts, rest, in, out, c.comm)
}
Expand Down
29 changes: 20 additions & 9 deletions provisioner/ansible/scp.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ func scpUploadSession(opts []byte, rest string, in io.Reader, out io.Writer, com
}
defer os.RemoveAll(d)

state := &scpUploadState{destRoot: rest, srcRoot: d, comm: comm}
// To properly implement scp, rest should be checked to see if it is a
// directory on the remote side, but ansible only sends files, so there's no
// need to set targetIsDir, because it can be safely assumed that rest is
// intended to be a file, and whatever names are used in 'C' commands are
// irrelavant.
state := &scpUploadState{target: rest, srcRoot: d, comm: comm}

fmt.Fprintf(out, scpOK) // signal the client to start the transfer.
return state.Protocol(bufio.NewReader(in), out)
Expand Down Expand Up @@ -117,16 +122,17 @@ func (state *scpDownloadState) FileProtocol(path string, info os.FileInfo, in *b
}

type scpUploadState struct {
comm packer.Communicator
destRoot string // destRoot is the directory on the target
srcRoot string // srcRoot is the directory on the host
mtime time.Time
atime time.Time
dir string // dir is a path relative to the roots
comm packer.Communicator
target string // target is the directory on the target
srcRoot string // srcRoot is the directory on the host
mtime time.Time
atime time.Time
dir string // dir is a path relative to the roots
targetIsDir bool
}

func (scp scpUploadState) DestPath() string {
return filepath.Join(scp.destRoot, scp.dir)
return filepath.Join(scp.target, scp.dir)
}

func (scp scpUploadState) SrcPath() string {
Expand Down Expand Up @@ -177,7 +183,12 @@ func (state *scpUploadState) FileProtocol(in *bufio.Reader, out io.Writer) error

var fi os.FileInfo = fileInfo{name: name, size: size, mode: mode, mtime: state.mtime}

err = state.comm.Upload(filepath.Join(state.DestPath(), fi.Name()), io.LimitReader(in, fi.Size()), &fi)
dest := state.DestPath()
if state.targetIsDir {
dest = filepath.Join(dest, fi.Name())
}

err = state.comm.Upload(dest, io.LimitReader(in, fi.Size()), &fi)
if err != nil {
fmt.Fprintf(out, scpEmptyError)
return err
Expand Down
5 changes: 3 additions & 2 deletions test/fixtures/provisioner-ansible/all_options.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "ansible",
"playbook_file": "./playbook.yml",
"extra_arguments": [
"-vvvv", "--private-key", "ansible-test-id"
"--private-key", "ansible-test-id"
],
"sftp_command": "/usr/lib/sftp-server -e -l INFO",
"use_sftp": true,
Expand All @@ -35,6 +35,7 @@
"project_id": "{{user `project_id`}}",
"image_name": "packerbats-alloptions-{{timestamp}}",
"source_image": "debian-7-wheezy-v20141108",
"zone": "us-central1-a"
"zone": "us-central1-a",
"ssh_username": "root"
}]
}
16 changes: 16 additions & 0 deletions test/fixtures/provisioner-ansible/connection_plugins/packer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.plugins.connection.ssh import Connection as SSHConnection

class Connection(SSHConnection):
''' ssh based connections for powershell via packer'''

transport = 'packer'
has_pipelining = True
become_methods = []
allow_executable = False
module_implementation_preferences = ('.ps1', '')

def __init__(self, *args, **kwargs):
super(Connection, self).__init__(*args, **kwargs)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this file's parent directory should not be transferred to the node.
1 change: 1 addition & 0 deletions test/fixtures/provisioner-ansible/dir/subdir/file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file and its parent directory should be transferred to the node.
3 changes: 2 additions & 1 deletion test/fixtures/provisioner-ansible/minimal.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"project_id": "{{user `project_id`}}",
"image_name": "packerbats-minimal-{{timestamp}}",
"source_image": "debian-7-wheezy-v20141108",
"zone": "us-central1-a"
"zone": "us-central1-a",
"ssh_username": "root"
}
]
}
26 changes: 20 additions & 6 deletions test/fixtures/provisioner-ansible/playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@
- hosts: default:packer-test
gather_facts: no
tasks:
- raw: touch /root/ansible-raw-test
- raw: date
- command: echo "the command module"
- command: mkdir /tmp/remote-dir
- name: touch /root/ansible-raw-test
raw: touch /root/ansible-raw-test
- name: raw test
raw: date
- name: command test
command: echo "the command module"
- name: prepare remote directory
command: mkdir /tmp/remote-dir
args:
creates: /tmp/remote-dir
- copy: src=dir/file.txt dest=/tmp/remote-dir/file.txt
- fetch: src=/tmp/remote-dir/file.txt dest=fetched-dir validate=yes fail_on_missing=yes
- name: transfer file.txt
copy: src=dir/file.txt dest=/tmp/remote-dir/file.txt
- name: fetch file.text
fetch: src=/tmp/remote-dir/file.txt dest=fetched-dir validate=yes fail_on_missing=yes
- name: copy contents of directory
copy: src=dir/contents-only/ dest=/tmp/remote-dir
- name: fetch contents of directory
fetch: src=/tmp/remote-dir/file.txt dest="fetched-dir/{{ inventory_hostname }}/tmp/remote-dir/contents-only/" flat=yes validate=yes fail_on_missing=yes
- name: copy directory recursively
copy: src=dir/subdir dest=/tmp/remote-dir
- name: fetch recursively copied directory
fetch: src=/tmp/remote-dir/subdir/file.txt dest=fetched-dir validate=yes fail_on_missing=yes
- copy: src=largish-file.txt dest=/tmp/largish-file.txt
25 changes: 25 additions & 0 deletions test/fixtures/provisioner-ansible/scp-to-sftp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"variables": {},
"provisioners": [
{
"type": "ansible",
"playbook_file": "./playbook.yml",
"extra_arguments": [
],
"sftp_command": "/usr/bin/false",
"use_sftp": false
}
],
"builders": [
{
"type": "googlecompute",
"account_file": "{{user `account_file`}}",
"project_id": "{{user `project_id`}}",
"image_name": "packerbats-scp-to-sftp-{{timestamp}}",
"source_image": "debian-7-wheezy-v20141108",
"zone": "us-central1-a",
"ssh_username": "root",
"ssh_file_transfer_method": "sftp"
}
]
}
7 changes: 4 additions & 3 deletions test/fixtures/provisioner-ansible/scp.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"type": "ansible",
"playbook_file": "./playbook.yml",
"extra_arguments": [
"-vvvv"
],
"sftp_command": "/usr/bin/false"
"sftp_command": "/usr/bin/false",
"use_sftp": false
}
],
"builders": [
Expand All @@ -17,7 +17,8 @@
"project_id": "{{user `project_id`}}",
"image_name": "packerbats-scp-{{timestamp}}",
"source_image": "debian-7-wheezy-v20141108",
"zone": "us-central1-a"
"zone": "us-central1-a",
"ssh_username": "root"
}
]
}
4 changes: 2 additions & 2 deletions test/fixtures/provisioner-ansible/sftp.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"type": "googlecompute",
"account_file": "{{user `account_file`}}",
"project_id": "{{user `project_id`}}",

"image_name": "packerbats-sftp-{{timestamp}}",
"source_image": "debian-7-wheezy-v20141108",
"zone": "us-central1-a"
"zone": "us-central1-a",
"ssh_username": "root"
}
]
}
17 changes: 17 additions & 0 deletions test/fixtures/provisioner-ansible/win-playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
- hosts: default:packer-test
gather_facts: no
tasks:
#- debug: msg="testing regular modules that function with Windows: raw, fetch, slurp, setup"
- name: raw test
raw: date /t
- debug: msg="testing windows modules"
#- win_file: path=tmp/remote-dir state=directory
#- name: win_shell test
#win_shell: date /t
- name: win_copy test
win_copy: src=dir/file.txt dest=file.txt
#- win_copy: src=dir/file.txt dest=/tmp/remote-dir/file.txt
#- fetch: src=/tmp/remote-dir/file.txt dest=fetched-dir validate=yes fail_on_missing=yes
#- win_copy: src=largish-file.txt dest=/tmp/largish-file.txt
- debug: msg="packer does not support downloading from windows"
31 changes: 31 additions & 0 deletions test/fixtures/provisioner-ansible/winrm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"variables": {},
"provisioners": [
{
"type": "ansible",
"playbook_file": "./win-playbook.yml",
"extra_arguments": [
"--connection", "packer",
"--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None"
]
}
],
"builders": [
{
"type": "googlecompute",
"account_file": "{{user `account_file`}}",
"project_id": "{{user `project_id`}}",
"image_name": "packerbats-winrm-{{timestamp}}",
"source_image": "windows-server-2012-r2-dc-v20160916",
"communicator": "winrm",
"zone": "us-central1-a",
"disk_size": 50,
"winrm_username": "packer",
"winrm_use_ssl": true,
"winrm_insecure": true,
"metadata": {
"sysprep-specialize-script-cmd": "winrm set winrm/config/service/auth @{Basic=\"true\"}"
}
}
]
}
16 changes: 16 additions & 0 deletions test/provisioner_ansible.bats
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ teardown() {
diff -r dir fetched-dir/default/tmp/remote-dir > /dev/null
}

@test "ansible provisioner: build scp-to-sftp.json" {
cd $FIXTURE_ROOT
run packer build ${USER_VARS} $FIXTURE_ROOT/scp-to-sftp.json
[ "$status" -eq 0 ]
[ "$(gc_has_image "packerbats-scp-to-sftp")" -eq 1 ]
diff -r dir fetched-dir/default/tmp/remote-dir > /dev/null
}

@test "ansible provisioner: build sftp.json" {
cd $FIXTURE_ROOT
run packer build ${USER_VARS} $FIXTURE_ROOT/sftp.json
Expand All @@ -75,3 +83,11 @@ teardown() {
diff -r dir fetched-dir/default/tmp/remote-dir > /dev/null
}

@test "ansible provisioner: build winrm.json" {
cd $FIXTURE_ROOT
run packer build ${USER_VARS} $FIXTURE_ROOT/winrm.json
[ "$status" -eq 0 ]
[ "$(gc_has_image "packerbats-winrm")" -eq 1 ]
echo "packer does not support downloading files from download, skipping verification"
#diff -r dir fetched-dir/default/tmp/remote-dir > /dev/null
}
Loading