Triton plugin breakout (#10963)
This commit is contained in:
parent
f161f2bed2
commit
2cd296874e
|
@ -1,195 +0,0 @@
|
|||
//go:generate packer-sdc struct-markdown
|
||||
|
||||
package triton
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
tgo "github.com/joyent/triton-go"
|
||||
"github.com/joyent/triton-go/authentication"
|
||||
"github.com/joyent/triton-go/compute"
|
||||
"github.com/joyent/triton-go/network"
|
||||
)
|
||||
|
||||
// AccessConfig is for common configuration related to Triton access
|
||||
type AccessConfig struct {
|
||||
// The URL of the Triton cloud API to use. If omitted
|
||||
// it will default to the us-sw-1 region of the Joyent Public cloud. If you
|
||||
// are using your own private Triton installation you will have to supply the
|
||||
// URL of the cloud API of your own Triton installation.
|
||||
Endpoint string `mapstructure:"triton_url" required:"false"`
|
||||
// The username of the Triton account to use when
|
||||
// using the Triton Cloud API.
|
||||
Account string `mapstructure:"triton_account" required:"true"`
|
||||
// The username of a user who has access to your
|
||||
// Triton account.
|
||||
Username string `mapstructure:"triton_user" required:"false"`
|
||||
// The fingerprint of the public key of the SSH key
|
||||
// pair to use for authentication with the Triton Cloud API. If
|
||||
// triton_key_material is not set, it is assumed that the SSH agent has the
|
||||
// private key corresponding to this key ID loaded.
|
||||
KeyID string `mapstructure:"triton_key_id" required:"true"`
|
||||
// Path to the file in which the private key
|
||||
// of triton_key_id is stored. For example /home/soandso/.ssh/id_rsa. If
|
||||
// this is not specified, the SSH agent is used to sign requests with the
|
||||
// triton_key_id specified.
|
||||
KeyMaterial string `mapstructure:"triton_key_material" required:"false"`
|
||||
//secure_skip_tls_verify - (bool) This allows skipping TLS verification
|
||||
// of the Triton endpoint. It is useful when connecting to a temporary Triton
|
||||
// installation such as Cloud-On-A-Laptop which does not generally use a
|
||||
// certificate signed by a trusted root CA. The default is false.
|
||||
InsecureSkipTLSVerify bool `mapstructure:"insecure_skip_tls_verify" required:"false"`
|
||||
|
||||
signer authentication.Signer
|
||||
}
|
||||
|
||||
// Prepare performs basic validation on the AccessConfig and ensures we can sign
|
||||
// a request.
|
||||
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
var errs []error
|
||||
|
||||
if c.Endpoint == "" {
|
||||
// Use Joyent public cloud as the default endpoint if none is specified
|
||||
c.Endpoint = "https://us-sw-1.api.joyent.com"
|
||||
}
|
||||
|
||||
if c.Account == "" {
|
||||
errs = append(errs, errors.New("triton_account is required to use the triton builder"))
|
||||
}
|
||||
|
||||
if c.KeyID == "" {
|
||||
errs = append(errs, errors.New("triton_key_id is required to use the triton builder"))
|
||||
}
|
||||
|
||||
if c.KeyMaterial == "" {
|
||||
signer, err := c.createSSHAgentSigner()
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
c.signer = signer
|
||||
} else {
|
||||
signer, err := c.createPrivateKeySigner()
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
c.signer = signer
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) createSSHAgentSigner() (authentication.Signer, error) {
|
||||
input := authentication.SSHAgentSignerInput{
|
||||
KeyID: c.KeyID,
|
||||
AccountName: c.Account,
|
||||
Username: c.Username,
|
||||
}
|
||||
signer, err := authentication.NewSSHAgentSigner(input)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating Triton request signer: %s", err)
|
||||
}
|
||||
|
||||
// Ensure we can sign a request
|
||||
_, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC", false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error signing test request: %s", err)
|
||||
}
|
||||
|
||||
return signer, nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) createPrivateKeySigner() (authentication.Signer, error) {
|
||||
var privateKeyMaterial []byte
|
||||
var err error
|
||||
|
||||
// Check for keyMaterial being a file path
|
||||
if _, err = os.Stat(c.KeyMaterial); err != nil {
|
||||
privateKeyMaterial = []byte(c.KeyMaterial)
|
||||
} else {
|
||||
privateKeyMaterial, err = ioutil.ReadFile(c.KeyMaterial)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading key material from path '%s': %s",
|
||||
c.KeyMaterial, err)
|
||||
}
|
||||
}
|
||||
|
||||
input := authentication.PrivateKeySignerInput{
|
||||
KeyID: c.KeyID,
|
||||
AccountName: c.Account,
|
||||
Username: c.Username,
|
||||
PrivateKeyMaterial: privateKeyMaterial,
|
||||
}
|
||||
|
||||
signer, err := authentication.NewPrivateKeySigner(input)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating Triton request signer: %s", err)
|
||||
}
|
||||
|
||||
// Ensure we can sign a request
|
||||
_, err = signer.Sign("Wed, 26 Apr 2017 16:01:11 UTC", false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error signing test request: %s", err)
|
||||
}
|
||||
|
||||
return signer, nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) CreateTritonClient() (*Client, error) {
|
||||
|
||||
config := &tgo.ClientConfig{
|
||||
AccountName: c.Account,
|
||||
TritonURL: c.Endpoint,
|
||||
Username: c.Username,
|
||||
Signers: []authentication.Signer{c.signer},
|
||||
}
|
||||
|
||||
return &Client{
|
||||
config: config,
|
||||
insecureSkipTLSVerify: c.InsecureSkipTLSVerify,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
config *tgo.ClientConfig
|
||||
insecureSkipTLSVerify bool
|
||||
}
|
||||
|
||||
func (c *Client) Compute() (*compute.ComputeClient, error) {
|
||||
computeClient, err := compute.NewClient(c.config)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf("Error Creating Triton Compute Client: {{err}}", err)
|
||||
}
|
||||
|
||||
if c.insecureSkipTLSVerify {
|
||||
computeClient.Client.InsecureSkipTLSVerify()
|
||||
}
|
||||
|
||||
return computeClient, nil
|
||||
}
|
||||
|
||||
func (c *Client) Network() (*network.NetworkClient, error) {
|
||||
networkClient, err := network.NewClient(c.config)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf("Error Creating Triton Network Client: {{err}}", err)
|
||||
}
|
||||
|
||||
if c.insecureSkipTLSVerify {
|
||||
networkClient.Client.InsecureSkipTLSVerify()
|
||||
}
|
||||
|
||||
return networkClient, nil
|
||||
}
|
||||
|
||||
func (c *AccessConfig) Comm() communicator.Config {
|
||||
return communicator.Config{}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccessConfig_Prepare(t *testing.T) {
|
||||
ac := testAccessConfig()
|
||||
errs := ac.Prepare(nil)
|
||||
if errs != nil {
|
||||
t.Fatal("should not error")
|
||||
}
|
||||
|
||||
ac = testAccessConfig()
|
||||
ac.Account = ""
|
||||
errs = ac.Prepare(nil)
|
||||
if errs == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
|
||||
ac = testAccessConfig()
|
||||
ac.KeyID = ""
|
||||
errs = ac.Prepare(nil)
|
||||
if errs == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
}
|
||||
|
||||
func testAccessConfig() AccessConfig {
|
||||
return AccessConfig{
|
||||
Endpoint: "test-endpoint",
|
||||
Account: "test-account",
|
||||
KeyID: "c5:9d:37:d2:28:d3:ef:39:1b:0a:0e:37:d5:b4:7c:59",
|
||||
KeyMaterial: testKeyMaterial,
|
||||
}
|
||||
}
|
||||
|
||||
const testKeyMaterial = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpgIBAAKCAQEAuujYxDCBu9W6es650mLcy9RaLGqjHT2KXPs4fHVr1sfBxPDk
|
||||
ChpekrVEfE69wpf7/oduQwLmBTIBBNtr/aH5e8gt2uCe1kD6swjnAG+nWZB63/BW
|
||||
XF9zFFE/Vs/dOyHIkqoLhVHurYYFBGqDXH4w1N02vfyQaH/VQDumF9ZiH6b9u28/
|
||||
WtrHSLPeGidgrt3csh0Q4Bydm2xSCx4Kfeouv0rM25mFoiq/QaTXkfWS0sIzrhhU
|
||||
rXL4N6B8tBRojHghpjh8LjG4ufJ7Q0QMWfeBfTqQ9llaEtiMIBznyq+oF7vwv0pc
|
||||
Cw2eXcURfg/9e5M8S3gSthkqGN9NjQUSeNsgCQIDAQABAoIBAQCcy6zcmFyc+GTh
|
||||
lP5psanMDC5BSIvhgbjK26y9K7v1h8nTrsl+eDSSGiKDrYKe9eTd1zr2WD4iaZpV
|
||||
OsVTFkg2QO3Gydw1nHkzK+qtgP0As6WAqxunjiL6DlZ2OxY5/tNFxgS4KM1zIBSh
|
||||
acEdHHdWeuTraC60m1iH9AIXyS6zoW+YvKr3Cu+gjQgDxg90Uzx7gB7/tAT9uTCG
|
||||
NHXRCJFrjLlKwWap5QpbbrEMZXjwwb4FEC6KOWaTHDGtB6V2NHBYfpAucuLXx19H
|
||||
jKUnogZHxTFbYwf7oZSVCR6tUm/Dytq0DmZv+wkCtUSqP0hljqO71yOOMiWA7fVq
|
||||
4cyD8TGJAoGBAPVVebrIEm8gMTt7s37YFwZXXcC2GT/jVi5bOhWhL5zOA0VxJMH7
|
||||
hUmrRNffNbFciSUM7CeSqh7Zq9v2l+qCjy9iZfUN6NY1s7d5q7NVkVX/GBuZ8ULp
|
||||
d81L4ifnr9KsEIzWz8X3Y/efO/20YqoEqLJm6qUyZYHWJbv9Z8Cteef7AoGBAMMJ
|
||||
HkzRop/VAi5RFzuJyNEzeOyveGpngtsnAY/UcEeWoxkUfHy/GAZAH8aAz9FqLaBv
|
||||
xGL++g3l8nHtov+gkrnJpK/f0QEWY+PbRWxSRHLW0rBdQJRB8nisNrWJwj4ysNhj
|
||||
ejYgBfSSmwkLBnvjNce6RwtZ5d+VRFGRl63CfMTLAoGBAK7Vaxqg2gI3ft5VGWWb
|
||||
uUzblgRvwS62ZARFHu+rHrMwXURvjTJwfFwzoav1dd4fg9zTiLfq3TF/DeqDoV+O
|
||||
C1xJUz9/2h5NxvVJ0ALNR/VxBU0mN7jniGjVWyX1BmesF19G9mquEp+06puyoV1o
|
||||
VJBOp4lykMQmSF3gCMBW4DlhAoGBAINdauk28iBRqqxjthBGF9rAnpxc+/A/VCYk
|
||||
OasU3aN6VNSZtdeYJqhfHIfpTxCwQZckcNR1BRvDW+9crkMbdnho1uIXEIF5AUMB
|
||||
99qj9rKa+0ILLWoumRCqfhb8eLbIEdFN/4zhOOGotX/7yxw6x4iFcUC2Blz3/xIp
|
||||
zE4fB0bNAoGBAK/ms0TixeqdNCY8WVHjT6H1W34Y1gvMlwSDodlUk0v8rUHAK4bO
|
||||
TKvdCYbxCQ+kqAFlicY1ZwxoeJzW6k3K+kJ+qWBn0yH4W61M8uKOIvciu1w1CXxG
|
||||
XZHg281yLxOfJj9YnPG73+sZFucyhtNPiq/1pR4tpm6YLMk8KSTy7XU5
|
||||
-----END RSA PRIVATE KEY-----`
|
|
@ -1,53 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Artifact is an artifact implementation that contains built Triton images.
|
||||
type Artifact struct {
|
||||
// ImageID is the image ID of the artifact
|
||||
ImageID string
|
||||
|
||||
// BuilderIDValue is the unique ID for the builder that created this Image
|
||||
BuilderIDValue string
|
||||
|
||||
// SDC connection for cleanup etc
|
||||
Driver Driver
|
||||
|
||||
// StateData should store data such as GeneratedData
|
||||
// to be shared with post-processors
|
||||
StateData map[string]interface{}
|
||||
}
|
||||
|
||||
func (a *Artifact) BuilderId() string {
|
||||
return a.BuilderIDValue
|
||||
}
|
||||
|
||||
func (*Artifact) Files() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Artifact) Id() string {
|
||||
return a.ImageID
|
||||
}
|
||||
|
||||
func (a *Artifact) String() string {
|
||||
return fmt.Sprintf("Image was created: %s", a.ImageID)
|
||||
}
|
||||
|
||||
func (a *Artifact) State(name string) interface{} {
|
||||
//TODO(jen20): Figure out how to make this work with Atlas
|
||||
return a.StateData[name]
|
||||
}
|
||||
|
||||
func (a *Artifact) Destroy() error {
|
||||
log.Printf("Deleting image ID (%s)", a.ImageID)
|
||||
err := a.Driver.DeleteImage(a.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep/commonsteps"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/config"
|
||||
)
|
||||
|
||||
const (
|
||||
BuilderId = "joyent.triton"
|
||||
)
|
||||
|
||||
type Builder struct {
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstructure().HCL2Spec() }
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
|
||||
errs := &multierror.Error{}
|
||||
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
PluginType: BuilderId,
|
||||
Interpolate: true,
|
||||
InterpolateContext: &b.config.ctx,
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
|
||||
errs = multierror.Append(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
|
||||
errs = multierror.Append(errs, b.config.SourceMachineConfig.Prepare(&b.config.ctx)...)
|
||||
errs = multierror.Append(errs, b.config.Comm.Prepare(&b.config.ctx)...)
|
||||
errs = multierror.Append(errs, b.config.TargetImageConfig.Prepare(&b.config.ctx)...)
|
||||
|
||||
// If we are using an SSH agent to sign requests, and no private key has been
|
||||
// specified for SSH, use the agent for connecting for provisioning.
|
||||
if b.config.AccessConfig.KeyMaterial == "" && b.config.Comm.SSHPrivateKeyFile == "" {
|
||||
b.config.Comm.SSHAgentAuth = true
|
||||
}
|
||||
|
||||
return nil, nil, errs.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook) (packersdk.Artifact, error) {
|
||||
config := b.config
|
||||
|
||||
driver, err := NewDriverTriton(ui, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", &b.config)
|
||||
state.Put("debug", b.config.PackerDebug)
|
||||
state.Put("driver", driver)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
|
||||
steps := []multistep.Step{
|
||||
&StepCreateSourceMachine{},
|
||||
&communicator.StepConnect{
|
||||
Config: &config.Comm,
|
||||
Host: commHost(b.config.Comm.Host()),
|
||||
SSHConfig: b.config.Comm.SSHConfigFunc(),
|
||||
},
|
||||
&commonsteps.StepProvision{},
|
||||
&commonsteps.StepCleanupTempKeys{
|
||||
Comm: &config.Comm,
|
||||
},
|
||||
&StepStopMachine{},
|
||||
&StepCreateImageFromMachine{},
|
||||
&StepDeleteMachine{},
|
||||
}
|
||||
|
||||
b.runner = commonsteps.NewRunnerWithPauseFn(steps, b.config.PackerConfig, ui, state)
|
||||
b.runner.Run(ctx, state)
|
||||
|
||||
// If there was an error, return that
|
||||
if rawErr, ok := state.GetOk("error"); ok {
|
||||
return nil, rawErr.(error)
|
||||
}
|
||||
|
||||
// If there is no image, just return
|
||||
if _, ok := state.GetOk("image"); !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
artifact := &Artifact{
|
||||
ImageID: state.Get("image").(string),
|
||||
BuilderIDValue: BuilderId,
|
||||
Driver: driver,
|
||||
StateData: map[string]interface{}{"generated_data": state.Get("generated_data")},
|
||||
}
|
||||
|
||||
return artifact, nil
|
||||
}
|
||||
|
||||
// Cancel cancels a possibly running Builder. This should block until
|
||||
// the builder actually cancels and cleans up after itself.
|
|
@ -1,20 +0,0 @@
|
|||
//go:generate packer-sdc mapstructure-to-hcl2 -type Config
|
||||
|
||||
package triton
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
"github.com/hashicorp/packer-plugin-sdk/communicator"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
AccessConfig `mapstructure:",squash"`
|
||||
SourceMachineConfig `mapstructure:",squash"`
|
||||
TargetImageConfig `mapstructure:",squash"`
|
||||
|
||||
Comm communicator.Config `mapstructure:",squash"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
|
||||
|
||||
package triton
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/config"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
|
||||
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
|
||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"`
|
||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"`
|
||||
Endpoint *string `mapstructure:"triton_url" required:"false" cty:"triton_url" hcl:"triton_url"`
|
||||
Account *string `mapstructure:"triton_account" required:"true" cty:"triton_account" hcl:"triton_account"`
|
||||
Username *string `mapstructure:"triton_user" required:"false" cty:"triton_user" hcl:"triton_user"`
|
||||
KeyID *string `mapstructure:"triton_key_id" required:"true" cty:"triton_key_id" hcl:"triton_key_id"`
|
||||
KeyMaterial *string `mapstructure:"triton_key_material" required:"false" cty:"triton_key_material" hcl:"triton_key_material"`
|
||||
InsecureSkipTLSVerify *bool `mapstructure:"insecure_skip_tls_verify" required:"false" cty:"insecure_skip_tls_verify" hcl:"insecure_skip_tls_verify"`
|
||||
MachineName *string `mapstructure:"source_machine_name" required:"false" cty:"source_machine_name" hcl:"source_machine_name"`
|
||||
MachinePackage *string `mapstructure:"source_machine_package" required:"true" cty:"source_machine_package" hcl:"source_machine_package"`
|
||||
MachineImage *string `mapstructure:"source_machine_image" required:"true" cty:"source_machine_image" hcl:"source_machine_image"`
|
||||
MachineNetworks []string `mapstructure:"source_machine_networks" required:"false" cty:"source_machine_networks" hcl:"source_machine_networks"`
|
||||
MachineMetadata map[string]string `mapstructure:"source_machine_metadata" required:"false" cty:"source_machine_metadata" hcl:"source_machine_metadata"`
|
||||
MachineTags map[string]string `mapstructure:"source_machine_tags" required:"false" cty:"source_machine_tags" hcl:"source_machine_tags"`
|
||||
MachineTag []config.FlatKeyValue `mapstructure:"source_machine_tag" required:"false" cty:"source_machine_tag" hcl:"source_machine_tag"`
|
||||
MachineFirewallEnabled *bool `mapstructure:"source_machine_firewall_enabled" required:"false" cty:"source_machine_firewall_enabled" hcl:"source_machine_firewall_enabled"`
|
||||
MachineImageFilters *FlatMachineImageFilter `mapstructure:"source_machine_image_filter" required:"false" cty:"source_machine_image_filter" hcl:"source_machine_image_filter"`
|
||||
ImageName *string `mapstructure:"image_name" required:"true" cty:"image_name" hcl:"image_name"`
|
||||
ImageVersion *string `mapstructure:"image_version" required:"true" cty:"image_version" hcl:"image_version"`
|
||||
ImageDescription *string `mapstructure:"image_description" required:"false" cty:"image_description" hcl:"image_description"`
|
||||
ImageHomepage *string `mapstructure:"image_homepage" required:"false" cty:"image_homepage" hcl:"image_homepage"`
|
||||
ImageEULA *string `mapstructure:"image_eula_url" required:"false" cty:"image_eula_url" hcl:"image_eula_url"`
|
||||
ImageACL []string `mapstructure:"image_acls" required:"false" cty:"image_acls" hcl:"image_acls"`
|
||||
ImageTags map[string]string `mapstructure:"image_tags" required:"false" cty:"image_tags" hcl:"image_tags"`
|
||||
ImageTag []config.FlatNameValue `mapstructure:"image_tag" required:"false" cty:"image_tag" hcl:"image_tag"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
|
||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"`
|
||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"`
|
||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"`
|
||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"`
|
||||
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"`
|
||||
SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"`
|
||||
SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"`
|
||||
SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"`
|
||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"`
|
||||
SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"`
|
||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"`
|
||||
SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"`
|
||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"`
|
||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"`
|
||||
SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"`
|
||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"`
|
||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"`
|
||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"`
|
||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"`
|
||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"`
|
||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"`
|
||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"`
|
||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"`
|
||||
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"`
|
||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"`
|
||||
SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"`
|
||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"`
|
||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"`
|
||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"`
|
||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"`
|
||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"`
|
||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"`
|
||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"`
|
||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"`
|
||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"`
|
||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"`
|
||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"`
|
||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"`
|
||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"`
|
||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"`
|
||||
WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"`
|
||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"`
|
||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"`
|
||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"`
|
||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"`
|
||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
// FlatConfig is an auto-generated flat version of Config.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatConfig)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a Config.
|
||||
// This spec is used by HCL to read the fields of Config.
|
||||
// The decoded values from this spec will then be applied to a FlatConfig.
|
||||
func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
"packer_user_variables": &hcldec.AttrSpec{Name: "packer_user_variables", Type: cty.Map(cty.String), Required: false},
|
||||
"packer_sensitive_variables": &hcldec.AttrSpec{Name: "packer_sensitive_variables", Type: cty.List(cty.String), Required: false},
|
||||
"triton_url": &hcldec.AttrSpec{Name: "triton_url", Type: cty.String, Required: false},
|
||||
"triton_account": &hcldec.AttrSpec{Name: "triton_account", Type: cty.String, Required: false},
|
||||
"triton_user": &hcldec.AttrSpec{Name: "triton_user", Type: cty.String, Required: false},
|
||||
"triton_key_id": &hcldec.AttrSpec{Name: "triton_key_id", Type: cty.String, Required: false},
|
||||
"triton_key_material": &hcldec.AttrSpec{Name: "triton_key_material", Type: cty.String, Required: false},
|
||||
"insecure_skip_tls_verify": &hcldec.AttrSpec{Name: "insecure_skip_tls_verify", Type: cty.Bool, Required: false},
|
||||
"source_machine_name": &hcldec.AttrSpec{Name: "source_machine_name", Type: cty.String, Required: false},
|
||||
"source_machine_package": &hcldec.AttrSpec{Name: "source_machine_package", Type: cty.String, Required: false},
|
||||
"source_machine_image": &hcldec.AttrSpec{Name: "source_machine_image", Type: cty.String, Required: false},
|
||||
"source_machine_networks": &hcldec.AttrSpec{Name: "source_machine_networks", Type: cty.List(cty.String), Required: false},
|
||||
"source_machine_metadata": &hcldec.AttrSpec{Name: "source_machine_metadata", Type: cty.Map(cty.String), Required: false},
|
||||
"source_machine_tags": &hcldec.AttrSpec{Name: "source_machine_tags", Type: cty.Map(cty.String), Required: false},
|
||||
"source_machine_tag": &hcldec.BlockListSpec{TypeName: "source_machine_tag", Nested: hcldec.ObjectSpec((*config.FlatKeyValue)(nil).HCL2Spec())},
|
||||
"source_machine_firewall_enabled": &hcldec.AttrSpec{Name: "source_machine_firewall_enabled", Type: cty.Bool, Required: false},
|
||||
"source_machine_image_filter": &hcldec.BlockSpec{TypeName: "source_machine_image_filter", Nested: hcldec.ObjectSpec((*FlatMachineImageFilter)(nil).HCL2Spec())},
|
||||
"image_name": &hcldec.AttrSpec{Name: "image_name", Type: cty.String, Required: false},
|
||||
"image_version": &hcldec.AttrSpec{Name: "image_version", Type: cty.String, Required: false},
|
||||
"image_description": &hcldec.AttrSpec{Name: "image_description", Type: cty.String, Required: false},
|
||||
"image_homepage": &hcldec.AttrSpec{Name: "image_homepage", Type: cty.String, Required: false},
|
||||
"image_eula_url": &hcldec.AttrSpec{Name: "image_eula_url", Type: cty.String, Required: false},
|
||||
"image_acls": &hcldec.AttrSpec{Name: "image_acls", Type: cty.List(cty.String), Required: false},
|
||||
"image_tags": &hcldec.AttrSpec{Name: "image_tags", Type: cty.Map(cty.String), Required: false},
|
||||
"image_tag": &hcldec.BlockListSpec{TypeName: "image_tag", Nested: hcldec.ObjectSpec((*config.FlatNameValue)(nil).HCL2Spec())},
|
||||
"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},
|
||||
"temporary_key_pair_type": &hcldec.AttrSpec{Name: "temporary_key_pair_type", Type: cty.String, Required: false},
|
||||
"temporary_key_pair_bits": &hcldec.AttrSpec{Name: "temporary_key_pair_bits", Type: cty.Number, Required: false},
|
||||
"ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
|
||||
"ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false},
|
||||
"ssh_private_key_file": &hcldec.AttrSpec{Name: "ssh_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_certificate_file": &hcldec.AttrSpec{Name: "ssh_certificate_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_wait_timeout": &hcldec.AttrSpec{Name: "ssh_wait_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_interactive": &hcldec.AttrSpec{Name: "ssh_bastion_interactive", Type: cty.Bool, Required: false},
|
||||
"ssh_bastion_private_key_file": &hcldec.AttrSpec{Name: "ssh_bastion_private_key_file", Type: cty.String, Required: false},
|
||||
"ssh_bastion_certificate_file": &hcldec.AttrSpec{Name: "ssh_bastion_certificate_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_no_proxy": &hcldec.AttrSpec{Name: "winrm_no_proxy", Type: cty.Bool, 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},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testConfig(t *testing.T) *Config {
|
||||
return &Config{
|
||||
AccessConfig: testAccessConfig(),
|
||||
SourceMachineConfig: testSourceMachineConfig(t),
|
||||
TargetImageConfig: testTargetImageConfig(t),
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Driver interface {
|
||||
GetImage(config Config) (string, error)
|
||||
CreateImageFromMachine(machineId string, config Config) (string, error)
|
||||
CreateMachine(config Config) (string, error)
|
||||
DeleteImage(imageId string) error
|
||||
DeleteMachine(machineId string) error
|
||||
GetMachineIP(machineId string) (string, error)
|
||||
StopMachine(machineId string) error
|
||||
WaitForImageCreation(imageId string, timeout time.Duration) error
|
||||
WaitForMachineDeletion(machineId string, timeout time.Duration) error
|
||||
WaitForMachineState(machineId string, state string, timeout time.Duration) error
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type DriverMock struct {
|
||||
CreateImageFromMachineId string
|
||||
CreateImageFromMachineErr error
|
||||
|
||||
CreateMachineId string
|
||||
CreateMachineErr error
|
||||
|
||||
DeleteImageId string
|
||||
DeleteImageErr error
|
||||
|
||||
DeleteMachineId string
|
||||
DeleteMachineErr error
|
||||
|
||||
GetImageId string
|
||||
GetImageErr error
|
||||
|
||||
GetMachineErr error
|
||||
|
||||
StopMachineId string
|
||||
StopMachineErr error
|
||||
|
||||
WaitForImageCreationErr error
|
||||
|
||||
WaitForMachineDeletionErr error
|
||||
|
||||
WaitForMachineStateErr error
|
||||
}
|
||||
|
||||
func (d *DriverMock) GetImage(config Config) (string, error) {
|
||||
if d.GetImageErr != nil {
|
||||
return "", d.GetImageErr
|
||||
}
|
||||
|
||||
return config.MachineImage, nil
|
||||
}
|
||||
|
||||
func (d *DriverMock) CreateImageFromMachine(machineId string, config Config) (string, error) {
|
||||
if d.CreateImageFromMachineErr != nil {
|
||||
return "", d.CreateImageFromMachineErr
|
||||
}
|
||||
|
||||
d.CreateImageFromMachineId = config.ImageName
|
||||
|
||||
return d.CreateImageFromMachineId, nil
|
||||
}
|
||||
|
||||
func (d *DriverMock) CreateMachine(config Config) (string, error) {
|
||||
if d.CreateMachineErr != nil {
|
||||
return "", d.CreateMachineErr
|
||||
}
|
||||
|
||||
d.CreateMachineId = config.MachineName
|
||||
|
||||
return d.CreateMachineId, nil
|
||||
}
|
||||
|
||||
func (d *DriverMock) DeleteImage(imageId string) error {
|
||||
if d.DeleteImageErr != nil {
|
||||
return d.DeleteImageErr
|
||||
}
|
||||
|
||||
d.DeleteImageId = imageId
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DriverMock) DeleteMachine(machineId string) error {
|
||||
if d.DeleteMachineErr != nil {
|
||||
return d.DeleteMachineErr
|
||||
}
|
||||
|
||||
d.DeleteMachineId = machineId
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DriverMock) GetMachineIP(machineId string) (string, error) {
|
||||
if d.GetMachineErr != nil {
|
||||
return "", d.GetMachineErr
|
||||
}
|
||||
|
||||
return "ip", nil
|
||||
}
|
||||
|
||||
func (d *DriverMock) StopMachine(machineId string) error {
|
||||
d.StopMachineId = machineId
|
||||
|
||||
return d.StopMachineErr
|
||||
}
|
||||
|
||||
func (d *DriverMock) WaitForImageCreation(machineId string, timeout time.Duration) error {
|
||||
return d.WaitForImageCreationErr
|
||||
}
|
||||
|
||||
func (d *DriverMock) WaitForMachineDeletion(machineId string, timeout time.Duration) error {
|
||||
return d.WaitForMachineDeletionErr
|
||||
}
|
||||
|
||||
func (d *DriverMock) WaitForMachineState(machineId string, state string, timeout time.Duration) error {
|
||||
return d.WaitForMachineStateErr
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/joyent/triton-go/compute"
|
||||
terrors "github.com/joyent/triton-go/errors"
|
||||
)
|
||||
|
||||
type driverTriton struct {
|
||||
client *Client
|
||||
ui packersdk.Ui
|
||||
}
|
||||
|
||||
func NewDriverTriton(ui packersdk.Ui, config Config) (Driver, error) {
|
||||
client, err := config.AccessConfig.CreateTritonClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &driverTriton{
|
||||
client: client,
|
||||
ui: ui,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *driverTriton) GetImage(config Config) (string, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
images, err := computeClient.Images().List(context.Background(), &compute.ListImagesInput{
|
||||
Name: config.MachineImageFilters.Name,
|
||||
OS: config.MachineImageFilters.OS,
|
||||
Version: config.MachineImageFilters.Version,
|
||||
Public: config.MachineImageFilters.Public,
|
||||
Type: config.MachineImageFilters.Type,
|
||||
State: config.MachineImageFilters.State,
|
||||
Owner: config.MachineImageFilters.Owner,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(images) == 0 {
|
||||
return "", errors.New("No images found in your search. Please refine your search criteria")
|
||||
}
|
||||
|
||||
if len(images) > 1 {
|
||||
if !config.MachineImageFilters.MostRecent {
|
||||
return "", errors.New("More than 1 machine image was found in your search. Please refine your search criteria")
|
||||
} else {
|
||||
return mostRecentImages(images).ID, nil
|
||||
}
|
||||
} else {
|
||||
return images[0].ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (d *driverTriton) CreateImageFromMachine(machineId string, config Config) (string, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
image, err := computeClient.Images().CreateFromMachine(context.Background(), &compute.CreateImageFromMachineInput{
|
||||
MachineID: machineId,
|
||||
Name: config.ImageName,
|
||||
Version: config.ImageVersion,
|
||||
Description: config.ImageDescription,
|
||||
HomePage: config.ImageHomepage,
|
||||
EULA: config.ImageEULA,
|
||||
ACL: config.ImageACL,
|
||||
Tags: config.ImageTags,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return image.ID, err
|
||||
}
|
||||
|
||||
func (d *driverTriton) CreateMachine(config Config) (string, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
input := &compute.CreateInstanceInput{
|
||||
Package: config.MachinePackage,
|
||||
Image: config.MachineImage,
|
||||
Metadata: config.MachineMetadata,
|
||||
Tags: config.MachineTags,
|
||||
FirewallEnabled: config.MachineFirewallEnabled,
|
||||
}
|
||||
|
||||
if config.MachineName == "" {
|
||||
// If not supplied generate a name for the source VM: "packer-builder-[image_name]".
|
||||
// The version is not used because it can contain characters invalid for a VM name.
|
||||
input.Name = "packer-builder-" + config.ImageName
|
||||
} else {
|
||||
input.Name = config.MachineName
|
||||
}
|
||||
|
||||
if len(config.MachineNetworks) > 0 {
|
||||
input.Networks = config.MachineNetworks
|
||||
}
|
||||
|
||||
machine, err := computeClient.Instances().Create(context.Background(), input)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return machine.ID, nil
|
||||
}
|
||||
|
||||
func (d *driverTriton) DeleteImage(imageId string) error {
|
||||
computeClient, _ := d.client.Compute()
|
||||
return computeClient.Images().Delete(context.Background(), &compute.DeleteImageInput{
|
||||
ImageID: imageId,
|
||||
})
|
||||
}
|
||||
|
||||
func (d *driverTriton) DeleteMachine(machineId string) error {
|
||||
computeClient, _ := d.client.Compute()
|
||||
return computeClient.Instances().Delete(context.Background(), &compute.DeleteInstanceInput{
|
||||
ID: machineId,
|
||||
})
|
||||
}
|
||||
|
||||
func (d *driverTriton) GetMachineIP(machineId string) (string, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
machine, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{
|
||||
ID: machineId,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return machine.PrimaryIP, nil
|
||||
}
|
||||
|
||||
func (d *driverTriton) StopMachine(machineId string) error {
|
||||
computeClient, _ := d.client.Compute()
|
||||
return computeClient.Instances().Stop(context.Background(), &compute.StopInstanceInput{
|
||||
InstanceID: machineId,
|
||||
})
|
||||
}
|
||||
|
||||
// waitForMachineState uses the supplied client to wait for the state of
|
||||
// the machine with the given ID to reach the state described in state.
|
||||
// If timeout is reached before the machine reaches the required state, an
|
||||
// error is returned. If the machine reaches the target state within the
|
||||
// timeout, nil is returned.
|
||||
func (d *driverTriton) WaitForMachineState(machineId string, state string, timeout time.Duration) error {
|
||||
return waitFor(
|
||||
func() (bool, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
machine, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{
|
||||
ID: machineId,
|
||||
})
|
||||
if machine == nil {
|
||||
return false, err
|
||||
}
|
||||
return machine.State == state, err
|
||||
},
|
||||
3*time.Second,
|
||||
timeout,
|
||||
)
|
||||
}
|
||||
|
||||
// waitForMachineDeletion uses the supplied client to wait for the machine
|
||||
// with the given ID to be deleted. It is expected that the API call to delete
|
||||
// the machine has already been issued at this point.
|
||||
func (d *driverTriton) WaitForMachineDeletion(machineId string, timeout time.Duration) error {
|
||||
return waitFor(
|
||||
func() (bool, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
_, err := computeClient.Instances().Get(context.Background(), &compute.GetInstanceInput{
|
||||
ID: machineId,
|
||||
})
|
||||
if err != nil {
|
||||
// Return true only when we receive a 410 (Gone) response. A 404
|
||||
// indicates that the machine is being deleted whereas a 410 indicates
|
||||
// that this process has completed.
|
||||
if terrors.IsSpecificStatusCode(err, http.StatusGone) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, err
|
||||
},
|
||||
3*time.Second,
|
||||
timeout,
|
||||
)
|
||||
}
|
||||
|
||||
func (d *driverTriton) WaitForImageCreation(imageId string, timeout time.Duration) error {
|
||||
return waitFor(
|
||||
func() (bool, error) {
|
||||
computeClient, _ := d.client.Compute()
|
||||
image, err := computeClient.Images().Get(context.Background(), &compute.GetImageInput{
|
||||
ImageID: imageId,
|
||||
})
|
||||
if image == nil {
|
||||
return false, err
|
||||
}
|
||||
return image.State == "active", err
|
||||
},
|
||||
3*time.Second,
|
||||
timeout,
|
||||
)
|
||||
}
|
||||
|
||||
func waitFor(f func() (bool, error), every, timeout time.Duration) error {
|
||||
start := time.Now()
|
||||
|
||||
for time.Since(start) <= timeout {
|
||||
stop, err := f()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if stop {
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(every)
|
||||
}
|
||||
|
||||
return errors.New("Timed out while waiting for resource change")
|
||||
}
|
||||
|
||||
func mostRecentImages(images []*compute.Image) *compute.Image {
|
||||
return sortImages(images)[0]
|
||||
}
|
||||
|
||||
type imageSort []*compute.Image
|
||||
|
||||
func sortImages(images []*compute.Image) []*compute.Image {
|
||||
sortedImages := images
|
||||
sort.Sort(sort.Reverse(imageSort(sortedImages)))
|
||||
return sortedImages
|
||||
}
|
||||
|
||||
func (a imageSort) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a imageSort) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a imageSort) Less(i, j int) bool {
|
||||
itime := a[i].PublishedAt
|
||||
jtime := a[j].PublishedAt
|
||||
return itime.Unix() < jtime.Unix()
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
//go:generate packer-sdc struct-markdown
|
||||
//go:generate packer-sdc mapstructure-to-hcl2 -type MachineImageFilter
|
||||
|
||||
package triton
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/config"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
// SourceMachineConfig represents the configuration to run a machine using
|
||||
// the SDC API in order for provisioning to take place.
|
||||
type SourceMachineConfig struct {
|
||||
// Name of the VM used for building the
|
||||
// image. Does not affect (and does not have to be the same) as the name for a
|
||||
// VM instance running this image. Maximum 512 characters but should in
|
||||
// practice be much shorter (think between 5 and 20 characters). For example
|
||||
// mysql-64-server-image-builder. When omitted defaults to
|
||||
// packer-builder-[image_name].
|
||||
MachineName string `mapstructure:"source_machine_name" required:"false"`
|
||||
// The Triton package to use while
|
||||
// building the image. Does not affect (and does not have to be the same) as
|
||||
// the package which will be used for a VM instance running this image. On the
|
||||
// Joyent public cloud this could for example be g3-standard-0.5-smartos.
|
||||
MachinePackage string `mapstructure:"source_machine_package" required:"true"`
|
||||
// The UUID of the image to base the new
|
||||
// image on. Triton supports multiple types of images, called 'brands' in
|
||||
// Triton / Joyent lingo, for contains and VM's. See the chapter Containers
|
||||
// and virtual machines in
|
||||
// the Joyent Triton documentation for detailed information. The following
|
||||
// brands are currently supported by this builder:joyent andkvm. The
|
||||
// choice of base image automatically decides the brand. On the Joyent public
|
||||
// cloud a valid source_machine_image could for example be
|
||||
// 70e3ae72-96b6-11e6-9056-9737fd4d0764 for version 16.3.1 of the 64bit
|
||||
// SmartOS base image (a 'joyent' brand image). source_machine_image_filter
|
||||
// can be used to populate this UUID.
|
||||
MachineImage string `mapstructure:"source_machine_image" required:"true"`
|
||||
// The UUID's of Triton
|
||||
// networks added to the source machine used for creating the image. For
|
||||
// example if any of the provisioners which are run need Internet access you
|
||||
// will need to add the UUID's of the appropriate networks here. If this is
|
||||
// not specified, instances will be placed into the default Triton public and
|
||||
// internal networks.
|
||||
MachineNetworks []string `mapstructure:"source_machine_networks" required:"false"`
|
||||
// Triton metadata
|
||||
// applied to the VM used to create the image. Metadata can be used to pass
|
||||
// configuration information to the VM without the need for networking. See
|
||||
// Using the metadata
|
||||
// API in the
|
||||
// Joyent documentation for more information. This can for example be used to
|
||||
// set the user-script metadata key to have Triton start a user supplied
|
||||
// script after the VM has booted.
|
||||
MachineMetadata map[string]string `mapstructure:"source_machine_metadata" required:"false"`
|
||||
// Key/value pair tags applied to the VM used to create the image.
|
||||
MachineTags map[string]string `mapstructure:"source_machine_tags" required:"false"`
|
||||
// Same as [`source_machine_tags`](#source_machine_tags) but defined as a
|
||||
// singular block containing a `key` and a `value` field. In HCL2 mode the
|
||||
// [`dynamic_block`](/docs/templates/hcl_templates/expressions#dynamic-blocks)
|
||||
// will allow you to create those programatically.
|
||||
MachineTag config.KeyValues `mapstructure:"source_machine_tag" required:"false"`
|
||||
// Whether or not the firewall
|
||||
// of the VM used to create an image of is enabled. The Triton firewall only
|
||||
// filters inbound traffic to the VM. All outbound traffic is always allowed.
|
||||
// Currently this builder does not provide an interface to add specific
|
||||
// firewall rules. Unless you have a global rule defined in Triton which
|
||||
// allows SSH traffic enabling the firewall will interfere with the SSH
|
||||
// provisioner. The default is false.
|
||||
MachineFirewallEnabled bool `mapstructure:"source_machine_firewall_enabled" required:"false"`
|
||||
// Filters used to populate the
|
||||
// source_machine_image field. Example:
|
||||
MachineImageFilters MachineImageFilter `mapstructure:"source_machine_image_filter" required:"false"`
|
||||
}
|
||||
|
||||
type MachineImageFilter struct {
|
||||
MostRecent bool `mapstructure:"most_recent"`
|
||||
Name string
|
||||
OS string
|
||||
Version string
|
||||
Public bool
|
||||
State string
|
||||
Owner string
|
||||
Type string
|
||||
}
|
||||
|
||||
func (m *MachineImageFilter) Empty() bool {
|
||||
return m.Name == "" && m.OS == "" && m.Version == "" && m.State == "" && m.Owner == "" && m.Type == ""
|
||||
}
|
||||
|
||||
// Prepare performs basic validation on a SourceMachineConfig struct.
|
||||
func (c *SourceMachineConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
var errs []error
|
||||
|
||||
if c.MachinePackage == "" {
|
||||
errs = append(errs, fmt.Errorf("A source_machine_package must be specified"))
|
||||
}
|
||||
|
||||
if c.MachineImage != "" && c.MachineImageFilters.Name != "" {
|
||||
errs = append(errs, fmt.Errorf("You cannot specify a Machine Image and also Machine Name filter"))
|
||||
}
|
||||
|
||||
if c.MachineNetworks == nil {
|
||||
c.MachineNetworks = []string{}
|
||||
}
|
||||
|
||||
if c.MachineMetadata == nil {
|
||||
c.MachineMetadata = make(map[string]string)
|
||||
}
|
||||
|
||||
if c.MachineTags == nil {
|
||||
c.MachineTags = make(map[string]string)
|
||||
}
|
||||
|
||||
errs = append(errs, c.MachineTag.CopyOn(&c.MachineTags)...)
|
||||
|
||||
return errs
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
|
||||
|
||||
package triton
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// FlatMachineImageFilter is an auto-generated flat version of MachineImageFilter.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatMachineImageFilter struct {
|
||||
MostRecent *bool `mapstructure:"most_recent" cty:"most_recent" hcl:"most_recent"`
|
||||
Name *string `cty:"name" hcl:"name"`
|
||||
OS *string `cty:"os" hcl:"os"`
|
||||
Version *string `cty:"version" hcl:"version"`
|
||||
Public *bool `cty:"public" hcl:"public"`
|
||||
State *string `cty:"state" hcl:"state"`
|
||||
Owner *string `cty:"owner" hcl:"owner"`
|
||||
Type *string `cty:"type" hcl:"type"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatMachineImageFilter.
|
||||
// FlatMachineImageFilter is an auto-generated flat version of MachineImageFilter.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*MachineImageFilter) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatMachineImageFilter)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a MachineImageFilter.
|
||||
// This spec is used by HCL to read the fields of MachineImageFilter.
|
||||
// The decoded values from this spec will then be applied to a FlatMachineImageFilter.
|
||||
func (*FlatMachineImageFilter) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"most_recent": &hcldec.AttrSpec{Name: "most_recent", Type: cty.Bool, Required: false},
|
||||
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
|
||||
"os": &hcldec.AttrSpec{Name: "os", Type: cty.String, Required: false},
|
||||
"version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false},
|
||||
"public": &hcldec.AttrSpec{Name: "public", Type: cty.Bool, Required: false},
|
||||
"state": &hcldec.AttrSpec{Name: "state", Type: cty.String, Required: false},
|
||||
"owner": &hcldec.AttrSpec{Name: "owner", Type: cty.String, Required: false},
|
||||
"type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSourceMachineConfig_Prepare(t *testing.T) {
|
||||
sc := testSourceMachineConfig(t)
|
||||
errs := sc.Prepare(nil)
|
||||
if errs != nil {
|
||||
t.Fatalf("should not error: %#v", sc)
|
||||
}
|
||||
|
||||
sc = testSourceMachineConfig(t)
|
||||
sc.MachineName = ""
|
||||
errs = sc.Prepare(nil)
|
||||
if errs != nil {
|
||||
t.Fatalf("should not error: %#v", sc)
|
||||
}
|
||||
|
||||
sc = testSourceMachineConfig(t)
|
||||
sc.MachinePackage = ""
|
||||
errs = sc.Prepare(nil)
|
||||
if errs == nil {
|
||||
t.Fatalf("should error: %#v", sc)
|
||||
}
|
||||
}
|
||||
|
||||
func testSourceMachineConfig(t *testing.T) SourceMachineConfig {
|
||||
return SourceMachineConfig{
|
||||
MachineName: "test-machine",
|
||||
MachinePackage: "test-package",
|
||||
MachineImage: "test-image",
|
||||
MachineNetworks: []string{
|
||||
"test-network-1",
|
||||
"test-network-2",
|
||||
},
|
||||
MachineMetadata: map[string]string{
|
||||
"test-metadata-key1": "test-metadata-value1",
|
||||
"test-metadata-key2": "test-metadata-value2",
|
||||
"test-metadata-key3": "test-metadata-value3",
|
||||
},
|
||||
MachineTags: map[string]string{
|
||||
"test-tags-key1": "test-tags-value1",
|
||||
"test-tags-key2": "test-tags-value2",
|
||||
"test-tags-key3": "test-tags-value3",
|
||||
},
|
||||
MachineFirewallEnabled: false,
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func commHost(host string) func(multistep.StateBag) (string, error) {
|
||||
return func(state multistep.StateBag) (string, error) {
|
||||
if host != "" {
|
||||
log.Printf("Using host value: %s", host)
|
||||
return host, nil
|
||||
}
|
||||
|
||||
driver := state.Get("driver").(Driver)
|
||||
machineID := state.Get("machine").(string)
|
||||
|
||||
machine, err := driver.GetMachineIP(machineID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return machine, nil
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
// StepCreateImageFromMachine creates an image with the specified attributes
|
||||
// from the machine with the given ID, and waits for the image to be created.
|
||||
// The machine must be in the "stopped" state prior to this step being run.
|
||||
type StepCreateImageFromMachine struct{}
|
||||
|
||||
func (s *StepCreateImageFromMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packersdk.Ui)
|
||||
|
||||
machineId := state.Get("machine").(string)
|
||||
|
||||
ui.Say("Creating image from source machine...")
|
||||
|
||||
imageId, err := driver.CreateImageFromMachine(machineId, *config)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("Problem creating image from machine: %s", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Say("Waiting for image to become available...")
|
||||
err = driver.WaitForImageCreation(imageId, 10*time.Minute)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("Problem waiting for image to become available: %s", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
state.Put("image", imageId)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepCreateImageFromMachine) Cleanup(state multistep.StateBag) {
|
||||
// No cleanup
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepCreateImageFromMachine(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateImageFromMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
state.Put("machine", "test-machine-id")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
_, ok := state.GetOk("image")
|
||||
if !ok {
|
||||
t.Fatalf("should have image")
|
||||
}
|
||||
|
||||
step.Cleanup(state)
|
||||
}
|
||||
|
||||
func TestStepCreateImageFromMachine_CreateImageFromMachineError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateImageFromMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
state.Put("machine", "test-machine-id")
|
||||
|
||||
driver.CreateImageFromMachineErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("image"); ok {
|
||||
t.Fatalf("should NOT have image")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateImageFromMachine_WaitForImageCreationError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateImageFromMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
state.Put("machine", "test-machine-id")
|
||||
|
||||
driver.WaitForImageCreationErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("image"); ok {
|
||||
t.Fatalf("should NOT have image")
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
// StepCreateSourceMachine creates an machine with the specified attributes
|
||||
// and waits for it to become available for provisioners.
|
||||
type StepCreateSourceMachine struct{}
|
||||
|
||||
func (s *StepCreateSourceMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packersdk.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)
|
||||
// instance_id is the generic term used so that users can have access to the
|
||||
// instance id inside of the provisioners, used in step_provision.
|
||||
state.Put("instance_id", machineId)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepCreateSourceMachine) Cleanup(state multistep.StateBag) {
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packersdk.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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepCreateSourceMachine(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateSourceMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
machineIdRaw, ok := state.GetOk("machine")
|
||||
if !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
|
||||
step.Cleanup(state)
|
||||
|
||||
if driver.DeleteMachineId != machineIdRaw.(string) {
|
||||
t.Fatalf("should've deleted machine (%s != %s)", driver.DeleteMachineId, machineIdRaw.(string))
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateSourceMachine_CreateMachineError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateSourceMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
driver.CreateMachineErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); ok {
|
||||
t.Fatalf("should NOT have machine")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateSourceMachine_WaitForMachineStateError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateSourceMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
driver.WaitForMachineStateErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); ok {
|
||||
t.Fatalf("should NOT have machine")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateSourceMachine_StopMachineError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateSourceMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
_, ok := state.GetOk("machine")
|
||||
if !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
|
||||
driver.StopMachineErr = errors.New("error")
|
||||
step.Cleanup(state)
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateSourceMachine_WaitForMachineStoppedError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateSourceMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
_, ok := state.GetOk("machine")
|
||||
if !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
|
||||
driver.WaitForMachineStateErr = errors.New("error")
|
||||
step.Cleanup(state)
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepCreateSourceMachine_DeleteMachineError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepCreateSourceMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
_, ok := state.GetOk("machine")
|
||||
if !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
|
||||
driver.DeleteMachineErr = errors.New("error")
|
||||
step.Cleanup(state)
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
// StepDeleteMachine deletes the machine with the ID specified in state["machine"]
|
||||
type StepDeleteMachine struct{}
|
||||
|
||||
func (s *StepDeleteMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packersdk.Ui)
|
||||
|
||||
machineId := state.Get("machine").(string)
|
||||
|
||||
ui.Say("Deleting source machine...")
|
||||
err := driver.DeleteMachine(machineId)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("Problem deleting source machine: %s", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Say("Waiting for source machine to be deleted...")
|
||||
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 multistep.ActionHalt
|
||||
}
|
||||
|
||||
state.Put("machine", "")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepDeleteMachine) Cleanup(state multistep.StateBag) {
|
||||
// No clean up to do here...
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepDeleteMachine(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepDeleteMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
machineId := "test-machine-id"
|
||||
state.Put("machine", machineId)
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
step.Cleanup(state)
|
||||
|
||||
if driver.DeleteMachineId != machineId {
|
||||
t.Fatalf("should've deleted machine (%s != %s)", driver.DeleteMachineId, machineId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepDeleteMachine_DeleteMachineError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepDeleteMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
machineId := "test-machine-id"
|
||||
state.Put("machine", machineId)
|
||||
|
||||
driver.DeleteMachineErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepDeleteMachine_WaitForMachineDeletionError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepDeleteMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
machineId := "test-machine-id"
|
||||
state.Put("machine", machineId)
|
||||
|
||||
driver.WaitForMachineDeletionErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("machine"); !ok {
|
||||
t.Fatalf("should have machine")
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
// StepStopMachine stops the machine with the given Machine ID, and waits
|
||||
// for it to reach the stopped state.
|
||||
type StepStopMachine struct{}
|
||||
|
||||
func (s *StepStopMachine) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
driver := state.Get("driver").(Driver)
|
||||
ui := state.Get("ui").(packersdk.Ui)
|
||||
|
||||
machineId := state.Get("machine").(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 multistep.ActionHalt
|
||||
}
|
||||
|
||||
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 multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepStopMachine) Cleanup(state multistep.StateBag) {
|
||||
// Explicitly don't clean up here as StepCreateSourceMachine will do it if necessary
|
||||
// and there is no real meaning to cleaning this up.
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
)
|
||||
|
||||
func TestStepStopMachine(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepStopMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
machineId := "test-machine-id"
|
||||
state.Put("machine", machineId)
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
step.Cleanup(state)
|
||||
|
||||
if driver.StopMachineId != machineId {
|
||||
t.Fatalf("should've stopped machine (%s != %s)", driver.StopMachineId, machineId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepStopMachine_StopMachineError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepStopMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
machineId := "test-machine-id"
|
||||
state.Put("machine", machineId)
|
||||
|
||||
driver.StopMachineErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepStopMachine_WaitForMachineStoppedError(t *testing.T) {
|
||||
state := testState(t)
|
||||
step := new(StepStopMachine)
|
||||
defer step.Cleanup(state)
|
||||
|
||||
driver := state.Get("driver").(*DriverMock)
|
||||
|
||||
machineId := "test-machine-id"
|
||||
state.Put("machine", machineId)
|
||||
|
||||
driver.WaitForMachineStateErr = errors.New("error")
|
||||
|
||||
if action := step.Run(context.Background(), state); action != multistep.ActionHalt {
|
||||
t.Fatalf("bad action: %#v", action)
|
||||
}
|
||||
|
||||
if _, ok := state.GetOk("error"); !ok {
|
||||
t.Fatalf("should have error")
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func testState(t *testing.T) multistep.StateBag {
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("config", testConfig(t))
|
||||
state.Put("driver", &DriverMock{})
|
||||
state.Put("hook", &packersdk.MockHook{})
|
||||
state.Put("ui", &packersdk.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
Writer: new(bytes.Buffer),
|
||||
})
|
||||
return state
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
// StepWaitForStopNotToFail waits for 10 seconds before returning with continue
|
||||
// in order to prevent an observed issue where machines stopped immediately after
|
||||
// they are started never actually stop.
|
||||
type StepWaitForStopNotToFail struct{}
|
||||
|
||||
func (s *StepWaitForStopNotToFail) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packersdk.Ui)
|
||||
ui.Say("Waiting 10 seconds to avoid potential SDC bug...")
|
||||
time.Sleep(10 * time.Second)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepWaitForStopNotToFail) Cleanup(state multistep.StateBag) {
|
||||
// No clean up required...
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
//go:generate packer-sdc struct-markdown
|
||||
|
||||
package triton
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/config"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template/interpolate"
|
||||
)
|
||||
|
||||
// TargetImageConfig represents the configuration for the image to be created
|
||||
// from the source machine.
|
||||
type TargetImageConfig struct {
|
||||
// The name the finished image in Triton will be
|
||||
// assigned. Maximum 512 characters but should in practice be much shorter
|
||||
// (think between 5 and 20 characters). For example postgresql-95-server for
|
||||
// an image used as a PostgreSQL 9.5 server.
|
||||
ImageName string `mapstructure:"image_name" required:"true"`
|
||||
// The version string for this image. Maximum 128
|
||||
// characters. Any string will do but a format of Major.Minor.Patch is
|
||||
// strongly advised by Joyent. See Semantic Versioning
|
||||
// for more information on the Major.Minor.Patch versioning format.
|
||||
ImageVersion string `mapstructure:"image_version" required:"true"`
|
||||
// Description of the image. Maximum 512
|
||||
// characters.
|
||||
ImageDescription string `mapstructure:"image_description" required:"false"`
|
||||
// URL of the homepage where users can find
|
||||
// information about the image. Maximum 128 characters.
|
||||
ImageHomepage string `mapstructure:"image_homepage" required:"false"`
|
||||
// URL of the End User License Agreement (EULA)
|
||||
// for the image. Maximum 128 characters.
|
||||
ImageEULA string `mapstructure:"image_eula_url" required:"false"`
|
||||
// The UUID's of the users which will have
|
||||
// access to this image. When omitted only the owner (the Triton user whose
|
||||
// credentials are used) will have access to the image.
|
||||
ImageACL []string `mapstructure:"image_acls" required:"false"`
|
||||
// Name/Value tags applied to the image.
|
||||
ImageTags map[string]string `mapstructure:"image_tags" required:"false"`
|
||||
// Same as [`image_tags`](#image_tags) but defined as a singular repeatable
|
||||
// block containing a `name` and a `value` field. In HCL2 mode the
|
||||
// [`dynamic_block`](/docs/templates/hcl_templates/expressions#dynamic-blocks)
|
||||
// will allow you to create those programatically.
|
||||
ImageTag config.NameValues `mapstructure:"image_tag" required:"false"`
|
||||
}
|
||||
|
||||
// Prepare performs basic validation on a TargetImageConfig struct.
|
||||
func (c *TargetImageConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
var errs []error
|
||||
|
||||
errs = append(errs, c.ImageTag.CopyOn(&c.ImageTags)...)
|
||||
|
||||
if c.ImageName == "" {
|
||||
errs = append(errs, fmt.Errorf("An image_name must be specified"))
|
||||
}
|
||||
|
||||
if c.ImageVersion == "" {
|
||||
errs = append(errs, fmt.Errorf("An image_version must be specified"))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package triton
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTargetImageConfig_Prepare(t *testing.T) {
|
||||
tic := testTargetImageConfig(t)
|
||||
errs := tic.Prepare(nil)
|
||||
if errs != nil {
|
||||
t.Fatalf("should not error: %#v", tic)
|
||||
}
|
||||
|
||||
tic = testTargetImageConfig(t)
|
||||
tic.ImageName = ""
|
||||
errs = tic.Prepare(nil)
|
||||
if errs == nil {
|
||||
t.Fatalf("should error: %#v", tic)
|
||||
}
|
||||
|
||||
tic = testTargetImageConfig(t)
|
||||
tic.ImageVersion = ""
|
||||
errs = tic.Prepare(nil)
|
||||
if errs == nil {
|
||||
t.Fatalf("should error: %#v", tic)
|
||||
}
|
||||
}
|
||||
|
||||
func testTargetImageConfig(t *testing.T) TargetImageConfig {
|
||||
return TargetImageConfig{
|
||||
ImageName: "test-image",
|
||||
ImageVersion: "test-version",
|
||||
ImageDescription: "test-description",
|
||||
ImageHomepage: "test-homepage",
|
||||
ImageEULA: "test-eula",
|
||||
ImageACL: []string{
|
||||
"test-acl-1",
|
||||
"test-acl-2",
|
||||
},
|
||||
ImageTags: map[string]string{
|
||||
"test-tags-key1": "test-tags-value1",
|
||||
"test-tags-key2": "test-tags-value2",
|
||||
"test-tags-key3": "test-tags-value3",
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package version
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer-plugin-sdk/version"
|
||||
packerVersion "github.com/hashicorp/packer/version"
|
||||
)
|
||||
|
||||
var TritonPluginVersion *version.PluginVersion
|
||||
|
||||
func init() {
|
||||
TritonPluginVersion = version.InitializePluginVersion(
|
||||
packerVersion.Version, packerVersion.VersionPrerelease)
|
||||
}
|
|
@ -24,7 +24,6 @@ import (
|
|||
oneandonebuilder "github.com/hashicorp/packer/builder/oneandone"
|
||||
profitbricksbuilder "github.com/hashicorp/packer/builder/profitbricks"
|
||||
tencentcloudcvmbuilder "github.com/hashicorp/packer/builder/tencentcloud/cvm"
|
||||
tritonbuilder "github.com/hashicorp/packer/builder/triton"
|
||||
yandexbuilder "github.com/hashicorp/packer/builder/yandex"
|
||||
artificepostprocessor "github.com/hashicorp/packer/post-processor/artifice"
|
||||
checksumpostprocessor "github.com/hashicorp/packer/post-processor/checksum"
|
||||
|
@ -62,7 +61,6 @@ var Builders = map[string]packersdk.Builder{
|
|||
"oneandone": new(oneandonebuilder.Builder),
|
||||
"profitbricks": new(profitbricksbuilder.Builder),
|
||||
"tencentcloud-cvm": new(tencentcloudcvmbuilder.Builder),
|
||||
"triton": new(tritonbuilder.Builder),
|
||||
"yandex": new(yandexbuilder.Builder),
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ import (
|
|||
puppetserverprovisioner "github.com/hashicorp/packer-plugin-puppet/provisioner/puppet-server"
|
||||
qemubuilder "github.com/hashicorp/packer-plugin-qemu/builder/qemu"
|
||||
scalewaybuilder "github.com/hashicorp/packer-plugin-scaleway/builder/scaleway"
|
||||
tritonbuilder "github.com/hashicorp/packer-plugin-triton/builder/triton"
|
||||
uclouduhostbuilder "github.com/hashicorp/packer-plugin-ucloud/builder/ucloud/uhost"
|
||||
ucloudimportpostprocessor "github.com/hashicorp/packer-plugin-ucloud/post-processor/ucloud-import"
|
||||
vagrantbuilder "github.com/hashicorp/packer-plugin-vagrant/builder/vagrant"
|
||||
|
@ -106,6 +107,7 @@ var VendoredBuilders = map[string]packersdk.Builder{
|
|||
"parallels-pvm": new(parallelspvmbuilder.Builder),
|
||||
"qemu": new(qemubuilder.Builder),
|
||||
"scaleway": new(scalewaybuilder.Builder),
|
||||
"triton": new(tritonbuilder.Builder),
|
||||
"ucloud-uhost": new(uclouduhostbuilder.Builder),
|
||||
"vagrant": new(vagrantbuilder.Builder),
|
||||
"vsphere-clone": new(vsphereclonebuilder.Builder),
|
||||
|
|
10
go.mod
10
go.mod
|
@ -16,10 +16,8 @@ require (
|
|||
github.com/cheggaaa/pb v1.0.27
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/digitalocean/godo v1.60.0
|
||||
github.com/dsnet/compress v0.0.1
|
||||
github.com/exoscale/packer-plugin-exoscale v0.1.1
|
||||
github.com/go-ini/ini v1.62.0
|
||||
github.com/go-resty/resty/v2 v2.3.0
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/google/go-cmp v0.5.5
|
||||
|
@ -27,13 +25,10 @@ require (
|
|||
github.com/google/uuid v1.2.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0
|
||||
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
|
||||
github.com/hashicorp/go-getter/v2 v2.0.0-20200604122502-a6995fa1edad
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-oracle-terraform v0.17.0
|
||||
github.com/hashicorp/go-uuid v1.0.2
|
||||
github.com/hashicorp/go-version v1.3.0
|
||||
github.com/hashicorp/hcl/v2 v2.10.0
|
||||
|
@ -52,7 +47,7 @@ require (
|
|||
github.com/hashicorp/packer-plugin-linode v0.0.2
|
||||
github.com/hashicorp/packer-plugin-ncloud v0.0.2
|
||||
github.com/hashicorp/packer-plugin-openstack v0.0.2
|
||||
github.com/hashicorp/packer-plugin-oracle v0.0.3 // indirect
|
||||
github.com/hashicorp/packer-plugin-oracle v0.0.3
|
||||
github.com/hashicorp/packer-plugin-outscale v0.0.1
|
||||
github.com/hashicorp/packer-plugin-parallels v0.0.1
|
||||
github.com/hashicorp/packer-plugin-proxmox v0.0.2
|
||||
|
@ -60,13 +55,13 @@ require (
|
|||
github.com/hashicorp/packer-plugin-qemu v0.0.1
|
||||
github.com/hashicorp/packer-plugin-scaleway v0.0.1
|
||||
github.com/hashicorp/packer-plugin-sdk v0.2.0
|
||||
github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9
|
||||
github.com/hashicorp/packer-plugin-ucloud v0.0.1
|
||||
github.com/hashicorp/packer-plugin-vagrant v0.0.3
|
||||
github.com/hashicorp/packer-plugin-virtualbox v0.0.1
|
||||
github.com/hashicorp/packer-plugin-vmware v0.0.1
|
||||
github.com/hashicorp/packer-plugin-vsphere v0.0.1
|
||||
github.com/hetznercloud/hcloud-go v1.15.1
|
||||
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62
|
||||
github.com/klauspost/pgzip v0.0.0-20151221113845-47f36e165cec
|
||||
github.com/masterzen/winrm v0.0.0-20201030141608-56ca5c5f2380
|
||||
github.com/mattn/go-tty v0.0.0-20191112051231-74040eebce08
|
||||
|
@ -76,7 +71,6 @@ require (
|
|||
github.com/mitchellh/panicwrap v1.0.0
|
||||
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784
|
||||
github.com/mitchellh/reflectwalk v1.0.0
|
||||
github.com/oracle/oci-go-sdk/v36 v36.2.0
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/posener/complete v1.2.3
|
||||
|
|
93
go.sum
93
go.sum
|
@ -87,6 +87,7 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0
|
|||
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.1.0/go.mod h1:P+3VS0ETiQPyWOx3vB/oeC8J3qd7jnVZLYAFwWgGRt8=
|
||||
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.2.0 h1:c7GgSBfMt51UGM4SI1F7IFOokOVZO+uxNcJL3Xsmkp4=
|
||||
github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.2.0/go.mod h1:P+3VS0ETiQPyWOx3vB/oeC8J3qd7jnVZLYAFwWgGRt8=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
|
@ -100,6 +101,8 @@ github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KM
|
|||
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
|
||||
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190418113227-25233c783f4e/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028 h1:lBif3zUMR6sjgfONVqfnjjjdXIK09S4Lvkze20ApE8w=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1028/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
|
||||
|
@ -126,6 +129,7 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkE
|
|||
github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43 h1:ePCAQPf5tUc5IMcUvu6euhSGna7jzs7eiXtJXHig6Zc=
|
||||
github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43/go.mod h1:S6puKjZ9ZeqUPBv2hEBnMZGcM2J6mOsDRQcmxkMAND0=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
|
||||
|
@ -168,6 +172,7 @@ github.com/aws/smithy-go v1.2.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAm
|
|||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
|
@ -179,6 +184,7 @@ github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9
|
|||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I=
|
||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc=
|
||||
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
|
@ -193,6 +199,14 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
@ -203,6 +217,7 @@ github.com/deepmap/oapi-codegen v1.5.1 h1:Xx8/OynzWhQeKFWr182hg6Ja2evS1gcqdja7qM
|
|||
github.com/deepmap/oapi-codegen v1.5.1/go.mod h1:Eb1vtV3f58zvm37CJV4UAQ1bECb0fgAVvTdonC1ftJg=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/digitalocean/go-libvirt v0.0.0-20190626172931-4d226dd6c437/go.mod h1:PRcPVAAma6zcLpFd4GZrjR/MRpood3TamjKI2m/z/Uw=
|
||||
github.com/digitalocean/go-libvirt v0.0.0-20201209184759-e2a69bcd5bd1/go.mod h1:QS1XzqZLcDniNYrN7EZefq3wIyb/M2WmJbql4ZKoc1Q=
|
||||
github.com/digitalocean/go-libvirt v0.0.0-20210108193637-3a8ae49ba8cd/go.mod h1:gtar3MgGsIO64GgphCHw1cbyxSI6qEuTIm9+izMmlfk=
|
||||
|
@ -223,6 +238,7 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
|
|||
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
||||
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI=
|
||||
github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ=
|
||||
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 h1:0bp6/GrNOrTDtSXe9YYGCwf8jp5Fb/b+4a6MTRm4qzY=
|
||||
|
@ -260,10 +276,13 @@ github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxm
|
|||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo=
|
||||
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-ini/ini v1.62.0 h1:7VJT/ZXjzqSrvtraFp4ONq80hTcRQth1c9ZnQ3uNQvU=
|
||||
github.com/go-ini/ini v1.62.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
|
||||
|
@ -278,6 +297,7 @@ github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr
|
|||
github.com/go-resty/resty/v2 v2.3.0 h1:JOOeAvjSlapTT92p8xiS19Zxev1neGikoHsXJeOq8So=
|
||||
github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
|
@ -288,6 +308,7 @@ github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
|
|||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
|
@ -296,6 +317,7 @@ github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:
|
|||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
|
@ -393,9 +415,13 @@ github.com/gophercloud/utils v0.0.0-20200508015959-b0167b94122c/go.mod h1:ehWUbL
|
|||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026 h1:BpJ2o0OR5FV7vrkDYfXYVJQeMNWa8RhklZOpW2ITAIQ=
|
||||
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
|
||||
github.com/hashicorp/aws-sdk-go-base v0.6.0/go.mod h1:2fRjWDv3jJBeN6mVWFHV6hFTNeFBx2gpDLQaZNxUVAY=
|
||||
|
@ -438,7 +464,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
|
|||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-oracle-terraform v0.0.0-20181016190316-007121241b79 h1:RKu7yAXZTaQsxj1K9GDsh+QVw0+Wu1SWHxtbFN0n+hE=
|
||||
github.com/hashicorp/go-oracle-terraform v0.0.0-20181016190316-007121241b79/go.mod h1:09jT3Y/OIsjTjQ2+3bkVNPDKqWcGIYYvjB2BEKVUdvc=
|
||||
github.com/hashicorp/go-oracle-terraform v0.17.0 h1:gFiaeKf9MXLobhv7uqzPuDFULL6ymJpw1NJCXwSOgJ4=
|
||||
github.com/hashicorp/go-oracle-terraform v0.17.0/go.mod h1:09jT3Y/OIsjTjQ2+3bkVNPDKqWcGIYYvjB2BEKVUdvc=
|
||||
|
@ -553,6 +578,8 @@ github.com/hashicorp/packer-plugin-sdk v0.1.3/go.mod h1:xePpgQgQYv/bamiypx3hH9uk
|
|||
github.com/hashicorp/packer-plugin-sdk v0.1.4/go.mod h1:xePpgQgQYv/bamiypx3hH9ukidxDdcN8q0R0wLi8IEQ=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.2.0 h1:A4Dq7p4y1vscY4gMzp7GQaXyDJYYhP4ukp4fapPSOY4=
|
||||
github.com/hashicorp/packer-plugin-sdk v0.2.0/go.mod h1:0DiOMEBldmB0HEhp0npFSSygC8bIvW43pphEgWkp2WU=
|
||||
github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9 h1:No5oPI9Wa7FhTKkFJwI3hcfUVvEpgPC8QMcG9l/Vxzo=
|
||||
github.com/hashicorp/packer-plugin-triton v0.0.0-20210421085122-768dd7c764d9/go.mod h1:XOAIiWYLbctBOsu41it/cL/ZjULAZ05YBhFm4H4M/lA=
|
||||
github.com/hashicorp/packer-plugin-ucloud v0.0.1 h1:SC2F1BuXb6dKhY6fRdmAqTkuc17jlBIu/Ut0URJy8TU=
|
||||
github.com/hashicorp/packer-plugin-ucloud v0.0.1/go.mod h1:xyMMmi/UPqFV3GT4eeX7wIqdoncNyrNuvdylnEQl1RU=
|
||||
github.com/hashicorp/packer-plugin-vagrant v0.0.3 h1:BT8l8PM6TBawBRuhpvyuA4QSW9/FvE7rhGgVaiRpXz8=
|
||||
|
@ -580,8 +607,12 @@ github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4 h1:mSmyzh
|
|||
github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4/go.mod h1:yNUVHSleURKSaYUKq4Wx0i/vjCen2aq7CvPyHd/Vj2Q=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jarcoal/httpmock v1.0.6/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
github.com/jarcoal/httpmock v1.0.8 h1:8kI16SoO6LQKgPE7PvQuV+YuD/inwHd7fOOe2zMbo4k=
|
||||
github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
|
@ -596,8 +627,10 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
|||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62 h1:JHCT6xuyPUrbbgAPE/3dqlvUKzRHMNuTBKKUb6OeR/k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA=
|
||||
github.com/joyent/triton-go v1.8.5 h1:AXc1BJP3YGAvQXIdhdJt/PiARN5arHNXWK6Q6FeBing=
|
||||
github.com/joyent/triton-go v1.8.5/go.mod h1:meGUPVGmmm+vhjIsOzfmJtuKpapVfWXJhUSLsr7Sv40=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
@ -609,6 +642,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
|||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
|
@ -630,6 +664,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
|||
github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169/go.mod h1:glhvuHOU9Hy7/8PwwdtnarXqLagOX0b/TbZx2zLMqEg=
|
||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
|
@ -641,9 +676,11 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LE
|
|||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||
github.com/labstack/echo/v4 v4.1.17/go.mod h1:Tn2yRQL/UclUalpb5rPdXDevbkJ+lp/2svdyFBg6CHQ=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/linode/linodego v0.14.0/go.mod h1:2ce3S00NrDqJfp4i55ZuSlT0U3cKNELNYACWBPI8Tnw=
|
||||
github.com/linode/linodego v1.0.0 h1:Kq/8oPPk3ui/aVlzEObll5oBewHyzo/eJPnVPYuONVE=
|
||||
github.com/linode/linodego v1.0.0/go.mod h1:XOWXRHjqeU2uPS84tKLgfWIfTlv3TYzCS0io4GOQzEI=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
|
@ -669,6 +706,7 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
|
|||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
||||
|
@ -720,11 +758,14 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20180105111133-96aac992fc8b/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
@ -745,6 +786,7 @@ github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a/go.mod h1
|
|||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
|
@ -761,15 +803,26 @@ github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXq
|
|||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible h1:ZoVHH6voxW9Onzo6z2yLtocVoN6mBocyDoqoyAMHokE=
|
||||
github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible/go.mod h1:T3/WrziK7fYH3C8ilAFAHe99R452/IzIG3YYkqaOFeQ=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
|
@ -778,6 +831,8 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
|||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7 h1:Do8ksLD4Nr3pA0x0hnLOLftZgkiTDvwPDShRTUxtXpE=
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
|
||||
github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac=
|
||||
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
|
@ -786,6 +841,8 @@ github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMT
|
|||
github.com/shirou/gopsutil v3.21.1+incompatible h1:2LwXWdbjXwyDgq26Yy/OT4xozlpmssQfy/rtfhWb0bY=
|
||||
github.com/shirou/gopsutil v3.21.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
|
@ -795,11 +852,21 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:X
|
|||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
|
@ -814,6 +881,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible h1:bs+0lcG4RELNbE8PsBC9oaPP0/qExr0DuEGnZyocm84=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ucloud/ucloud-sdk-go v0.16.3/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw=
|
||||
github.com/ucloud/ucloud-sdk-go v0.20.2 h1:ZNB38C7oZ2imCHEC79mVFvVT+ASkbryriOkZ+q2E0XI=
|
||||
|
@ -822,8 +890,10 @@ github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6/go.mod h1
|
|||
github.com/ufilesdk-dev/ufile-gosdk v1.0.1 h1:TNtFN3vO8ghuxLKBwQqSELllHYP4rggvXCox8JtVV0Y=
|
||||
github.com/ufilesdk-dev/ufile-gosdk v1.0.1/go.mod h1:R5FMQxkQ+QK/9Vz+jfnJP4rZIktYrRcWmuAnbOSkROI=
|
||||
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.2.4 h1:cTciPbZ/VSOzCLKclmssnfQ/jyoVyOcJ3aoJyUV1Urc=
|
||||
github.com/ugorji/go v1.2.4/go.mod h1:EuaSCk8iZMdIspsu6HXH7X2UGKw1ezO4wCfGszGmmo4=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.2.4 h1:C5VurWRRCKjuENsbM6GYVw8W++WVW9rSxoACKIvxzz8=
|
||||
github.com/ugorji/go/codec v1.2.4/go.mod h1:bWBu1+kIRWcF8uMklKaJrR6fTWQOwAlrIzX22pHwryA=
|
||||
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
|
@ -843,6 +913,8 @@ github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9o
|
|||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0/go.mod h1:sBh287mCRwCz6zyXHMmw7sSZGPohVpnx+o+OY4M+i3A=
|
||||
github.com/xanzy/go-cloudstack v2.4.1+incompatible h1:Oc4xa2+I94h1g/QJ+nHoq597nJz2KXzxuQx/weOx0AU=
|
||||
github.com/xanzy/go-cloudstack v2.4.1+incompatible/go.mod h1:s3eL3z5pNXF5FVybcT+LIVdId8pYn709yv6v5mrkrQE=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20200915125933-33de72a328bd h1:o4pvS7D4OErKOM6y+/q6IfOa65OaentKbEDh1ABirE8=
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20200915125933-33de72a328bd/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20200921111412-ef15ded2014c h1:LJrgyICodRAgtBvOO2eCbhDDIoaJgeLa1tGQecqW9ac=
|
||||
|
@ -862,6 +934,7 @@ github.com/zclconf/go-cty v1.8.2/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUA
|
|||
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
|
@ -875,12 +948,14 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
|||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -942,13 +1017,16 @@ golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -1012,6 +1090,9 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -1233,6 +1314,7 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE
|
|||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
|
@ -1265,6 +1347,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -1281,9 +1364,11 @@ gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
|||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181117152235-275e9df93516 h1:H6trpavCIuipdInWrab8l34Mf+GGVfphniHostMdMaQ=
|
||||
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181117152235-275e9df93516/go.mod h1:d3R+NllX3X5e0zlG1Rful3uLvsGC/Q3OHut5464DEQw=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
|
@ -1,218 +0,0 @@
|
|||
---
|
||||
description: >
|
||||
The triton Packer builder is able to create new images for use with Triton.
|
||||
|
||||
These images can be used with both the Joyent public cloud (which is powered
|
||||
by
|
||||
|
||||
Triton) as well with private Triton installations. This builder uses the
|
||||
Triton
|
||||
|
||||
Cloud API to create images.
|
||||
page_title: Triton - Builders
|
||||
---
|
||||
|
||||
# Triton Builder
|
||||
|
||||
Type: `triton`
|
||||
Artifact BuilderId: `joyent.triton`
|
||||
|
||||
The `triton` Packer builder is able to create new images for use with Triton.
|
||||
These images can be used with both the [Joyent public
|
||||
cloud](https://www.joyent.com/) (which is powered by Triton) as well with
|
||||
private [Triton](https://github.com/joyent/triton) installations.
|
||||
|
||||
This builder uses the Triton Cloud API to create these images. Triton also
|
||||
supports the Docker API however this builder does _not_. If you want to create
|
||||
Docker images on Triton you should use the Packer Docker builder.
|
||||
|
||||
The builder creates and launches a temporary VM based on a specified source
|
||||
image, runs any provisioning necessary, uses the Triton "VM to image"
|
||||
functionality to create a reusable image and finally destroys the temporary VM.
|
||||
This reusable image can then be used to launch new machines.
|
||||
|
||||
The builder does _not_ manage images. Once it creates an image, it is up to you
|
||||
to use it or delete it.
|
||||
|
||||
~> **Private installations of Triton must have custom images enabled!** To
|
||||
use the Triton builder with a private/on-prem installation of Joyent's Triton
|
||||
software, you'll need an operator to manually [enable custom
|
||||
images](https://docs.joyent.com/private-cloud/install/image-management) after
|
||||
installing Triton. This is not a requirement for Joyent's public cloud offering
|
||||
of Triton.
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
There are many configuration options available for the builder. They are
|
||||
segmented below into two categories: required and optional parameters.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
@include 'packer-plugin-sdk/communicator/SSH-Private-Key-File-not-required.mdx'
|
||||
|
||||
@include 'packer-plugin-sdk/communicator/SSH-Agent-Auth-not-required.mdx'
|
||||
|
||||
### Required:
|
||||
|
||||
- `triton_account` (string) - The username of the Triton account to use when
|
||||
using the Triton Cloud API.
|
||||
|
||||
- `triton_key_id` (string) - The fingerprint of the public key of the SSH key
|
||||
pair to use for authentication with the Triton Cloud API. If
|
||||
`triton_key_material` is not set, it is assumed that the SSH agent has the
|
||||
private key corresponding to this key ID loaded.
|
||||
|
||||
- `source_machine_image` (string) - The UUID of the image to base the new
|
||||
image on. Triton supports multiple types of images, called 'brands' in
|
||||
Triton / Joyent lingo, for contains and VM's. See the chapter [Containers
|
||||
and virtual machines](https://docs.joyent.com/public-cloud/instances) in
|
||||
the Joyent Triton documentation for detailed information. The following
|
||||
brands are currently supported by this builder:`joyent` and`kvm`. The
|
||||
choice of base image automatically decides the brand. On the Joyent public
|
||||
cloud a valid `source_machine_image` could for example be
|
||||
`70e3ae72-96b6-11e6-9056-9737fd4d0764` for version 16.3.1 of the 64bit
|
||||
SmartOS base image (a 'joyent' brand image). `source_machine_image_filter`
|
||||
can be used to populate this UUID.
|
||||
|
||||
- `source_machine_package` (string) - The Triton package to use while
|
||||
building the image. Does not affect (and does not have to be the same) as
|
||||
the package which will be used for a VM instance running this image. On the
|
||||
Joyent public cloud this could for example be `g3-standard-0.5-smartos`.
|
||||
|
||||
- `image_name` (string) - The name the finished image in Triton will be
|
||||
assigned. Maximum 512 characters but should in practice be much shorter
|
||||
(think between 5 and 20 characters). For example `postgresql-95-server` for
|
||||
an image used as a PostgreSQL 9.5 server.
|
||||
|
||||
- `image_version` (string) - The version string for this image. Maximum 128
|
||||
characters. Any string will do but a format of `Major.Minor.Patch` is
|
||||
strongly advised by Joyent. See [Semantic Versioning](http://semver.org/)
|
||||
for more information on the `Major.Minor.Patch` versioning format.
|
||||
|
||||
### Optional:
|
||||
|
||||
- `triton_url` (string) - The URL of the Triton cloud API to use. If omitted
|
||||
it will default to the `us-sw-1` region of the Joyent Public cloud. If you
|
||||
are using your own private Triton installation you will have to supply the
|
||||
URL of the cloud API of your own Triton installation.
|
||||
|
||||
- `triton_key_material` (string) - Path to the file in which the private key
|
||||
of `triton_key_id` is stored. For example `/home/soandso/.ssh/id_rsa`. If
|
||||
this is not specified, the SSH agent is used to sign requests with the
|
||||
`triton_key_id` specified.
|
||||
|
||||
- `triton_user` (string) - The username of a user who has access to your
|
||||
Triton account.
|
||||
|
||||
- `insecure_skip_tls_verify` - (bool) This allows skipping TLS verification
|
||||
of the Triton endpoint. It is useful when connecting to a temporary Triton
|
||||
installation such as Cloud-On-A-Laptop which does not generally use a
|
||||
certificate signed by a trusted root CA. The default is `false`.
|
||||
|
||||
- `source_machine_firewall_enabled` (boolean) - Whether or not the firewall
|
||||
of the VM used to create an image of is enabled. The Triton firewall only
|
||||
filters inbound traffic to the VM. All outbound traffic is always allowed.
|
||||
Currently this builder does not provide an interface to add specific
|
||||
firewall rules. Unless you have a global rule defined in Triton which
|
||||
allows SSH traffic enabling the firewall will interfere with the SSH
|
||||
provisioner. The default is `false`.
|
||||
|
||||
- `source_machine_metadata` (object of key/value strings) - Triton metadata
|
||||
applied to the VM used to create the image. Metadata can be used to pass
|
||||
configuration information to the VM without the need for networking. See
|
||||
[Using the metadata
|
||||
API](https://docs.joyent.com/private-cloud/instances/using-mdata) in the
|
||||
Joyent documentation for more information. This can for example be used to
|
||||
set the `user-script` metadata key to have Triton start a user supplied
|
||||
script after the VM has booted.
|
||||
|
||||
- `source_machine_name` (string) - Name of the VM used for building the
|
||||
image. Does not affect (and does not have to be the same) as the name for a
|
||||
VM instance running this image. Maximum 512 characters but should in
|
||||
practice be much shorter (think between 5 and 20 characters). For example
|
||||
`mysql-64-server-image-builder`. When omitted defaults to
|
||||
`packer-builder-[image_name]`.
|
||||
|
||||
- `source_machine_networks` (array of strings) - The UUID's of Triton
|
||||
networks added to the source machine used for creating the image. For
|
||||
example if any of the provisioners which are run need Internet access you
|
||||
will need to add the UUID's of the appropriate networks here. If this is
|
||||
not specified, instances will be placed into the default Triton public and
|
||||
internal networks.
|
||||
|
||||
- `source_machine_tags` (object of key/value strings) - Tags applied to the
|
||||
VM used to create the image.
|
||||
|
||||
- `image_acls` (array of strings) - The UUID's of the users which will have
|
||||
access to this image. When omitted only the owner (the Triton user whose
|
||||
credentials are used) will have access to the image.
|
||||
|
||||
- `image_description` (string) - Description of the image. Maximum 512
|
||||
characters.
|
||||
|
||||
- `image_eula_url` (string) - URL of the End User License Agreement (EULA)
|
||||
for the image. Maximum 128 characters.
|
||||
|
||||
- `image_homepage` (string) - URL of the homepage where users can find
|
||||
information about the image. Maximum 128 characters.
|
||||
|
||||
- `image_tags` (object of key/value strings) - Tag applied to the image.
|
||||
|
||||
- `source_machine_image_filter` (object) - Filters used to populate the
|
||||
`source_machine_image` field. Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"source_machine_image_filter": {
|
||||
"name": "ubuntu-16.04",
|
||||
"type": "lx-dataset",
|
||||
"most_recent": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Basic Example
|
||||
|
||||
Below is a minimal example to create an image on the Joyent public cloud:
|
||||
|
||||
```json
|
||||
{
|
||||
"builders": [
|
||||
{
|
||||
"type": "triton",
|
||||
|
||||
"triton_account": "triton_username",
|
||||
"triton_key_id": "6b:95:03:3d:d3:6e:52:69:01:96:1a:46:4a:8d:c1:7e",
|
||||
|
||||
"source_machine_name": "image-builder",
|
||||
"source_machine_package": "g4-highcpu-128M",
|
||||
"source_machine_image_filter": {
|
||||
"name": "ubuntu-16.04",
|
||||
"type": "lx-dataset",
|
||||
"most_recent": "true"
|
||||
},
|
||||
|
||||
"ssh_username": "root",
|
||||
|
||||
"image_name": "my_new_image",
|
||||
"image_version": "1.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
In the above example the SSH key used for `triton_key_material` (connecting to
|
||||
the Cloud API) and the `ssh_private_key_file` (connecting to the VM once it has
|
||||
started) are the same. This is because Triton automatically configures the root
|
||||
users to be able to login via SSH with the same key used to create the VM via
|
||||
the Cloud API. In more advanced scenarios for example when using a
|
||||
`source_machine_image` one might use different credentials.
|
||||
|
||||
Available `triton_key_id`, `source_machine_package`, `source_machine_image`,
|
||||
and `source_machine_networks` can be found by using the following [Triton
|
||||
CLI](https://docs.joyent.com/public-cloud/api-access/cloudapi) commands:
|
||||
`triton key list`, `triton package list`, `triton image list`, and
|
||||
`triton network list` respectively.
|
|
@ -728,10 +728,6 @@
|
|||
"title": "Tencent Cloud",
|
||||
"path": "builders/tencentcloud-cvm"
|
||||
},
|
||||
{
|
||||
"title": "Triton",
|
||||
"path": "builders/triton"
|
||||
},
|
||||
{
|
||||
"title": "Yandex.Cloud",
|
||||
"path": "builders/yandex"
|
||||
|
|
|
@ -146,6 +146,13 @@
|
|||
"pluginTier": "community",
|
||||
"version": "latest"
|
||||
},
|
||||
{
|
||||
"title": "Triton",
|
||||
"path": "triton",
|
||||
"repo": "hashicorp/packer-plugin-triton",
|
||||
"pluginTier": "community",
|
||||
"version": "latest"
|
||||
},
|
||||
{
|
||||
"title": "UCloud",
|
||||
"path": "ucloud",
|
||||
|
|
Loading…
Reference in New Issue