packer-cn/builder/triton/step_create_source_machine.go
stack72 7776bf596b builder/triton: Add a data source for source_machine_image
fixes: #5476

Based on this new template addition:

```
{
    "variables": {
        "image_version": "",
        "triton_account": "",
        "triton_key_id": "",
        "triton_key_material": ""
    },
    "builders": [{
        "type": "triton",
        "triton_account": "{{user `triton_account`}}",
        "triton_key_id": "{{user `triton_key_id`}}",
        "triton_key_material": "{{user `triton_key_material`}}",
        "source_machine_package": "g4-highcpu-128M",
        "source_machine_image_filter": {
          "name": "ubuntu-16.04",
          "most_recent": "true"
        },
        "ssh_username": "root",
        "image_version": "{{user `image_version`}}",
        "image_name": "teamcity-server"
    }],
    "provisioners": [
        {
            "type": "shell",
            "start_retry_timeout": "10m",
            "inline": [
                "sudo apt-get update -y",
                "sudo apt-get install -y nginx"
            ]
        }
    ]
}

```

I got the following output from packer:

```
packer-testing % make image
packer build \
		-var "triton_account=stack72_joyent" \
		-var "triton_key_id=40:9d:d3:f9:0b:86:62:48:f4:2e:a5:8e:43:00:2a:9b" \
		-var "triton_key_material=""" \
		-var "image_version=1.0.0" \
		new-template.json
triton output will be in this color.

==> triton: Selecting an image based on search criteria
==> triton: Based, on given search criteria, Machine ID is: "7b5981c4-1889-11e7-b4c5-3f3bdfc9b88b"
==> triton: Waiting for source machine to become available...
==> triton: Waiting for SSH to become available...
==> triton: Connected to SSH!
==> triton: Provisioning with shell script: /var/folders/_p/2_zj9lqn4n11fx20qy787p7c0000gn/T/packer-shell797317310
    triton: Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
    triton: Hit:2 http://archive.ubuntu.com/ubuntu xenial InRelease
```

I can verify from the triton cli tools that the id `7b5981c4` (from the packer output) is indeed the correct ID

```
terraform [master●] % triton images name=~ubuntu-16.04
SHORTID   NAME          VERSION   FLAGS  OS     TYPE        PUBDATE
49b22aec  ubuntu-16.04  20160427  P      linux  lx-dataset  2016-04-27
675834a0  ubuntu-16.04  20160505  P      linux  lx-dataset  2016-05-05
4edaa46a  ubuntu-16.04  20160516  P      linux  lx-dataset  2016-05-16
05140a7e  ubuntu-16.04  20160601  P      linux  lx-dataset  2016-06-01
e331b22a  ubuntu-16.04  20161004  P      linux  lx-dataset  2016-10-04
8879c758  ubuntu-16.04  20161213  P      linux  lx-dataset  2016-12-13
7b5981c4  ubuntu-16.04  20170403  P      linux  lx-dataset  2017-04-03 <------- THIS IS THE LATEST UBUNTU IMAGE
```
2017-11-02 16:10:16 +02:00

84 lines
2.6 KiB
Go

package triton
import (
"fmt"
"time"
"github.com/hashicorp/packer/packer"
"github.com/mitchellh/multistep"
)
// StepCreateSourceMachine creates an machine with the specified attributes
// and waits for it to become available for provisioners.
type StepCreateSourceMachine struct{}
func (s *StepCreateSourceMachine) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(Config)
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
if !config.MachineImageFilters.Empty() {
ui.Say("Selecting an image based on search criteria")
imageId, err := driver.GetImage(config)
if err != nil {
state.Put("error", fmt.Errorf("Problem selecting an image based on an search criteria: %s", err))
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Based, on given search criteria, Machine ID is: %q", imageId))
config.MachineImage = imageId
}
machineId, err := driver.CreateMachine(config)
if err != nil {
state.Put("error", fmt.Errorf("Problem creating source machine: %s", err))
return multistep.ActionHalt
}
ui.Say("Waiting for source machine to become available...")
err = driver.WaitForMachineState(machineId, "running", 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to become available: %s", err))
return multistep.ActionHalt
}
state.Put("machine", machineId)
return multistep.ActionContinue
}
func (s *StepCreateSourceMachine) Cleanup(state multistep.StateBag) {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
machineIdRaw, ok := state.GetOk("machine")
if ok && machineIdRaw.(string) != "" {
machineId := machineIdRaw.(string)
ui.Say(fmt.Sprintf("Stopping source machine (%s)...", machineId))
err := driver.StopMachine(machineId)
if err != nil {
state.Put("error", fmt.Errorf("Problem stopping source machine: %s", err))
return
}
ui.Say(fmt.Sprintf("Waiting for source machine to stop (%s)...", machineId))
err = driver.WaitForMachineState(machineId, "stopped", 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to stop: %s", err))
return
}
ui.Say(fmt.Sprintf("Deleting source machine (%s)...", machineId))
err = driver.DeleteMachine(machineId)
if err != nil {
state.Put("error", fmt.Errorf("Problem deleting source machine: %s", err))
return
}
ui.Say(fmt.Sprintf("Waiting for source machine to be destroyed (%s)...", machineId))
err = driver.WaitForMachineDeletion(machineId, 10*time.Minute)
if err != nil {
state.Put("error", fmt.Errorf("Problem waiting for source machine to be deleted: %s", err))
return
}
}
}